Skip to content

Commit

Permalink
修复检查是否跨越64K内存边界的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
acevest committed Sep 22, 2024
1 parent fef2233 commit e2f49a9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 24 deletions.
8 changes: 7 additions & 1 deletion drivers/ata.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,15 @@ void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest) {
unsigned long dest_paddr = va2pa(dest);

// 不能跨64K边界
#if 1
const uint32_t size = count * SECT_SIZE;
const uint32_t _64K = 1 << 16;
assert(((dest_paddr + size) & _64K) == (dest_paddr & _64K));
assert(((dest_paddr & (_64K - 1)) + size) <= _64K);
#else
const uint32_t size = count * SECT_SIZE;
const uint32_t _64K = 0xFFFF0000;
assert(((dest_paddr + size - (size == 0 ? 0 : 1)) & _64K) == (dest_paddr & _64K));
#endif

ide_ctrl->prdt[0].phys_addr = dest_paddr;
ide_ctrl->prdt[0].byte_count = size;
Expand Down
16 changes: 13 additions & 3 deletions kernel/task_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,19 @@ void send_disk_request(disk_request_t *r) {

// 校验buffer是否跨64K
// 先不处理
if (((uint32_t)r->buf & 0xFFFF0000) != (((uint32_t)(r->buf + r->count * 512)) & 0xFFFF0000)) {

#if 1
{
const uint32_t size = r->count * 512;
const uint32_t _64K = 1 << 16;
assert(((((uint32_t)r->buf) & (_64K - 1)) + size) <= _64K);
}
#else
if (((uint32_t)r->buf & 0xFFFF0000) != (((uint32_t)(r->buf + r->count * 512 - 1)) & 0xFFFF0000)) {
printk("dma read addr %08x count %d\n", r->buf, r->count);
panic("disk DMA read cross 64K");
}
#endif

mutex_lock(&drv->ide_pci_controller->request_mutex);
atomic_inc(&drv->ide_pci_controller->request_cnt);
Expand Down Expand Up @@ -98,14 +108,14 @@ void disk_task_entry(void *arg) {

switch (r->command) {
case DISK_REQ_IDENTIFY:
printk("try to read disk drive %u identify", drv_no);
printk("try to read disk drive %u identify\n", drv_no);
assert(r->count == 1);
ata_read_identify(drv_no, 0);
break;
case DISK_REQ_READ:
assert(r->count > 0);
assert(r->buf != NULL || r->bb->data != NULL);
// printk("DISK READ drv_no %u pos %u count %u\n", drv_no, (uint32_t)pos, r->count);
// printk("DISK READ drv_no %u pos %u count %u bb %x\n", drv_no, (uint32_t)pos, r->count, r->bb);
if (r->bb != 0) {
ata_dma_read_ext(drv_no, pos, r->count, r->bb->data);
} else {
Expand Down
41 changes: 21 additions & 20 deletions kernel/task_root.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,15 @@ void verify_hd_data(uint64_t sect_nr, uint16_t *buf, const char *name) {
}
}

u16 disk_buf1[256];
u16 disk_buf2[256];
// 保存它们不跨64KB
u16 disk_buf1[256] __attribute__((__aligned__(512)));
u16 disk_buf2[256] __attribute__((__aligned__(512)));

void taskA_entry() {
current->priority = 7;

while (1) {
sysc_wait(37);
sysc_wait(97);

uint64_t sect_nr = get_next_deubug_sect_nr();
memset(disk_buf1, 0, 512);
Expand All @@ -128,23 +129,23 @@ void taskB_entry() {
current->priority = 13;

while (1) {
sysc_wait(73);
uint64_t sect_nr = get_next_deubug_sect_nr();
memset(disk_buf2, 0, 512);
disk_request_t r;
r.dev = MAKE_DISK_DEV(2, 0);
r.command = DISK_REQ_READ;
r.pos = sect_nr;
r.count = 1;
r.buf = disk_buf2;
r.bb = 0;

send_disk_request(&r);
// verify_hd_data(sect_nr, disk_buf2, current->name);

for (int i = 0; i < 1; i++) {
asm("hlt;");
}
sysc_wait(7);
// uint64_t sect_nr = get_next_deubug_sect_nr();
// memset(disk_buf2, 0, 512);
// disk_request_t r;
// r.dev = MAKE_DISK_DEV(2, 0);
// r.command = DISK_REQ_READ;
// r.pos = sect_nr;
// r.count = 1;
// r.buf = disk_buf2;
// r.bb = 0;

// send_disk_request(&r);
// // verify_hd_data(sect_nr, disk_buf2, current->name);

// for (int i = 0; i < 1; i++) {
// asm("hlt;");
// }
}
}

Expand Down

0 comments on commit e2f49a9

Please sign in to comment.