// by writing a 0 to this bit. This results in all state information being lost (i.e., master mode
// operation cannot be stopped and then resumed).
- // 停止DMA,并设置为读(这里的WRITE是对DMA控制器来说)
- outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_STOP, ide_pci_controller.bus_cmd);
+ // 停止DMA
+ outb(PCI_IDE_CMD_STOP, ide_pci_controller.bus_cmd);
// 配置描述符表
unsigned long dest_paddr = va2pa(dest);
// 指定DMA操作为读取硬盘操作,内核用DMA读取,对硬盘而言是写出
// 并设置DMA的开始位,开始DMA
- outb(PCI_IDE_CMD_START, ide_pci_controller.bus_cmd);
+ outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_START, ide_pci_controller.bus_cmd);
}
// TODO
uint8_t ata_pci_bus_status();
extern ide_pci_controller_t ide_pci_controller;
+volatile uint32_t disk_inter_cnt = 0;
+
void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) {
// printk("ide irq handler %d \n", irq);
printk("ide irq %d handler pci status after interrupt: %x\n", irq, ata_pci_bus_status());
#if 1
+ disk_inter_cnt++;
up(&disk_intr_sem);
#else
ide_pci_controller.done = 1;
MPL_KEYBOARD,
MPL_IDE,
MPL_IDE_INTR,
- MPL_PREEMPT,
+ MPL_CURRENT,
MPL_TEST,
+ MPL_X,
MPL_DEBUG,
MPL_ROOT,
MPL_TASK_0,
unsigned long esp;
asm("movl %%esp, %%eax" : "=a"(esp));
- printl(MPL_PREEMPT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp);
+ printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp);
while (action && action->handler) {
action->handler(irq, regs, action->dev_id);
return s[state];
}
+extern uint32_t disk_request_cnt;
+extern uint32_t disk_handled_cnt;
+extern uint32_t disk_inter_cnt;
+
unsigned long schedule() {
task_union *sel = &root_task;
task_union *p = 0;
irq_save(iflags);
// printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt);
+ printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
+
#if 1
bool need_reset_weight = true;
list_for_each_safe(pos, t, &all_tasks) {
p = list_entry(pos, task_union, list);
+
+ if (p == &root_task) {
+ continue;
+ }
+
if (p->state != TASK_READY) {
continue;
}
list_for_each_safe(pos, t, &all_tasks) {
p = list_entry(pos, task_union, list);
+ if (p == &root_task) {
+ continue;
+ }
if (p->state != TASK_READY) {
continue;
}
semaphore_init(&disk_intr_sem, 0);
}
+volatile uint32_t disk_request_cnt = 0;
+volatile uint32_t disk_handled_cnt = 0;
void send_disk_request(disk_request_t *r) {
if (NULL == r) {
panic("null disk request");
#if 1
mutex_lock(&disk_request_mutex);
+ disk_request_cnt++;
list_add_tail(&r->list, &disk_request_queue.list);
mutex_unlock(&disk_request_mutex);
#else
}
list_del(&r->list);
+ disk_handled_cnt++;
mutex_unlock(&disk_request_mutex);
#else
unsigned long flags;
* ------------------------------------------------------------------------
*/
+#include <disk.h>
#include <fcntl.h>
#include <io.h>
#include <irq.h>
printk("kernel[%s] task pid is %d\n", name, pid);
}
+// 测试用的代码
+// 这里存的是下标对应的每个扇区的最后2个字节
+// hexdump -C HD.IMG | less 看的,如果镜像文件有变动需要更新这里
+uint16_t hd_sect_data_fingerprint[] = {
+ 0xAA55, // 0
+ 0x0820, // 1
+ 0x4d89, // 2
+ 0xeb1d, // 3
+ 0x1009 // 4
+};
+
+uint64_t debug_sect_nr = 0;
+
+uint64_t get_next_deubug_sect_nr() {
+ debug_sect_nr++;
+#if 0
+ debug_sect_nr %= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t);
+#else
+ if (debug_sect_nr >= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t)) {
+ debug_sect_nr = 0;
+ }
+#endif
+ return debug_sect_nr;
+}
+
+void verify_hd_data(uint64_t sect_nr, uint16_t *buf, const char *name) {
+ uint16_t vfp = hd_sect_data_fingerprint[sect_nr];
+
+ uint16_t fp = buf[255];
+
+ if (fp == vfp) {
+ printk("%s verification passed sect %lu fp %04x\n", name, sect_nr, fp);
+ } else {
+ printk("%s verification failed sect %lu fp %04x right %04x\n", name, sect_nr, fp, vfp);
+ panic("verify hd data fail");
+ }
+}
+
+u16 disk_buf1[256];
+u16 disk_buf2[256];
+
void taskA_entry() {
current->priority = 99;
while (1) {
- sysc_wait(600);
+ sysc_wait(7);
+
+ uint64_t sect_nr = get_next_deubug_sect_nr();
+ memset(disk_buf1, 0, 512);
+
+ disk_request_t r;
+ r.command = DISK_REQ_READ;
+ r.pos = sect_nr;
+ r.count = 1;
+ r.buf = disk_buf1;
+ send_disk_request(&r);
+
+ verify_hd_data(sect_nr, disk_buf1, current->name);
- for (int i = 0; i < 200; i++) {
+ for (int i = 0; i < 2; i++) {
asm("hlt;");
}
}
current->priority = 99;
while (1) {
- sysc_wait(200);
-
- for (int i = 0; i < 100; i++) {
+ sysc_wait(10);
+
+ uint64_t sect_nr = get_next_deubug_sect_nr();
+ memset(disk_buf2, 0, 512);
+ disk_request_t r;
+ r.command = DISK_REQ_READ;
+ r.pos = sect_nr;
+ r.count = 1;
+ r.buf = disk_buf2;
+ send_disk_request(&r);
+ verify_hd_data(sect_nr, disk_buf2, current->name);
+
+ for (int i = 0; i < 1; i++) {
asm("hlt;");
}
}
kernel_task("disk", disk_task_entry);
kernel_task("user", user_task_entry);
+ // for (int i = 0; i < 100; i++) {
+ // asm("hlt;");
+ // }
+
kernel_task("tskA", taskA_entry);
kernel_task("tskB", taskB_entry);
kernel_task("tskC", taskC_entry);
-boot d \
-drive file=HD.IMG,format=raw,index=0,media=disk \
-drive file=kernel.iso,index=1,media=cdrom \
+ -name kernel \
-s -S \
&