ide_pci_controller.prdt[0].eot = 1;
outl(va2pa(ide_pci_controller.prdt), ide_pci_controller.bus_prdt);
- printk("paddr: %x prdt: %x %x prdte %x %x\n", dest_paddr, ide_pci_controller.prdt, va2pa(ide_pci_controller.prdt),
- ide_pci_controller.prdt[0].phys_addr, *(((unsigned int *)ide_pci_controller.prdt) + 1));
+ // printk("paddr: %x prdt: %x %x prdte %x %x\n", dest_paddr, ide_pci_controller.prdt,
+ // va2pa(ide_pci_controller.prdt),
+ // ide_pci_controller.prdt[0].phys_addr, *(((unsigned int *)ide_pci_controller.prdt) + 1));
// 清除中断位和错误位
// 这里清除的方式是是设置1后清除
// Register)的值会一直是5 也就是INTERRUPT和和ACTIVE位是1,正常应该是4,也就是只有INTERRUPT位为1
// 在bochs中则加不加这一句不会有影响,都能正常读到数据
unsigned int v = pci_read_config_word(pci_cmd(ide_pci_controller.pci, PCI_COMMAND));
- printk(" ide pci command %04x\n", v);
+ // printk(" ide pci command %04x\n", v);
pci_write_config_word(v | PCI_COMMAND_MASTER, pci_cmd(ide_pci_controller.pci, PCI_COMMAND));
// 指定DMA操作为读取硬盘操作,内核用DMA读取,对硬盘而言是写出
unsigned int v;
v = pci_read_config_word(pci_cmd(pci, PCI_COMMAND));
- printk(" ide pci command %04x\n", v);
+ // printk(" ide pci command %04x\n", v);
v = pci_read_config_byte(pci_cmd(pci, PCI_PROGIF));
printk(" ide pci program interface %02x\n", v);
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: 0x%02x\n", irq, ata_pci_bus_status());
+ // printk("ide irq %d handler pci status: 0x%02x\n", irq, ata_pci_bus_status());
#if 1
disk_inter_cnt++;
MPL_IDE,
MPL_IDE_INTR,
MPL_CURRENT,
+ MPL_FUCK,
MPL_TEST,
MPL_X,
MPL_DEBUG,
#define TASK_NAME_SIZE 32
-#define TASK_MAX_PRIORITY 200
+#define TASK_MAX_PRIORITY 99
+
+#define TASK_MAGIC 0xAABBCCDD11223344
typedef union task_union {
struct {
uint32_t sched_keep_cnt; // 时间片到了,但是没有被换出,又重新执行的次数
uint64_t delay_jiffies; // debug only
+
+ uint64_t magic; // 栈溢出标志
};
unsigned char stack[TASK_SIZE];
#include <system.h>
#include <wait.h>
-volatile uint32_t jiffies = 0;
+volatile uint32_t jiffies = 0; // TODO uint64
unsigned int sys_clock() { return jiffies; }
+void debug_print_all_tasks();
+
+void dump_irq_nr_stack();
void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
if (jiffies % 100 == 0) {
printl(MPL_CLOCK, "clock irq: %d", jiffies);
jiffies++;
current->jiffies = jiffies;
+ // 若clk_handler嵌套在其它中断函数中执行
+ // 那么这个变量减到0时,再退出中clk_handler并不会引起调度
+ //
+
current->ticks--;
+ if (current->ticks > TASK_MAX_PRIORITY) {
+ printl(MPL_X, "current %08x ticks %u", current, current->ticks);
+ printk("DIE: ");
+ dump_irq_nr_stack();
+ }
assert(current->ticks <= TASK_MAX_PRIORITY); // 防止ticks被减到0后再减溢出
task_union *p = 0;
}
}
+ debug_print_all_tasks();
+ debug_print_all_tasks();
+ debug_print_all_tasks();
+ debug_print_all_tasks();
+
irq_restore(iflags);
}
tsk->priority = current->priority;
tsk->ticks = tsk->priority;
tsk->turn = 0; //
- root_task.sched_cnt = 0;
- root_task.sched_keep_cnt = 0;
+ tsk->sched_cnt = 0;
+ tsk->sched_keep_cnt = 0;
+ assert(tsk->magic == TASK_MAGIC);
pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1;
cmpl $0, (irq_reenter)
jnz restore_regs
+
+
call schedule
+ RESTORE_REGS
+ addl $4, %esp
+ iret
+
restore_regs:
RESTORE_REGS
addl $4, %esp
irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0};
+unsigned int irq_nr_stack[64] = {1, 2, 3, 4};
+uint32_t irq_nr_jiffies_stack[64] = {
+ 0,
+};
+int irq_nr_stack_pos = 0;
+
+extern uint32_t jiffies;
+void push_irq_nr_stack(unsigned int irq) {
+ irq_nr_stack[irq_nr_stack_pos] = irq;
+ irq_nr_jiffies_stack[irq_nr_stack_pos] = jiffies;
+ irq_nr_stack_pos++;
+}
+
+unsigned int pop_irq_nr_stack() {
+ irq_nr_stack_pos--;
+ return irq_nr_stack[irq_nr_stack_pos];
+}
+
+int vsprintf(char *buf, const char *fmt, char *args);
+void dump_irq_nr_stack() {
+ if (irq_nr_stack_pos == 0) {
+ printl(MPL_TEST, "irq nr stack empty");
+ return 0;
+ }
+
+ printl(MPL_FUCK, "irq nr stack pos %u", irq_nr_stack_pos);
+
+ char buf[128];
+
+ memset(buf, 0, 128);
+ strcpy(buf, "irq nr stack: ");
+ for (int i = 0; i < irq_nr_stack_pos; i++) {
+ char dbuf[64];
+ vsprintf(dbuf, "%02d:", irq_nr_stack + i); // 这里vsprintf有坑,坑点在第三个参数不是标准参数
+ strcat(buf, dbuf);
+ vsprintf(dbuf, "%d ", irq_nr_jiffies_stack + i);
+ strcat(buf, dbuf);
+ }
+
+ printl(MPL_TEST, " ");
+
+ printl(MPL_TEST, buf);
+ strcat(buf, "\n");
+ printk(buf);
+}
+
__attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
unsigned int irq = regs->irq;
if (irq >= NR_IRQS) {
irq_reenter++;
+ assert(current->magic == TASK_MAGIC);
+
+ push_irq_nr_stack(irq);
+
+ // if (irq_nr_stack_pos >= 2) {
+ dump_irq_nr_stack();
+ // panic("sdfasd");
+ // }
// 开中断执行中断处理函数
enable_irq();
-
unsigned long esp;
asm("movl %%esp, %%eax" : "=a"(esp));
printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp);
-
+ printk("2: %d r %d t %d\n", irq, irq_reenter, current->ticks);
while (action && action->handler) {
+ if (irq == 14) {
+ printk("a: %d r %d t %d \n", irq, irq_reenter, current->ticks);
+ }
action->handler(irq, regs, action->dev_id);
+ if (irq == 14) {
+ printk("b: %d r %d t %d \n", irq, irq_reenter, current->ticks);
+ }
action = action->next;
}
// 关全局中断
+ if (irq == 14) {
+ printk("c: %d r %d t %d \n", irq, irq_reenter, current->ticks);
+ }
disable_irq();
-
+ pop_irq_nr_stack();
irq_reenter--;
-
+ if (irq == 14) {
+ printk("d: %d r %d t %d \n", irq, irq_reenter, current->ticks);
+ }
// 解除屏蔽当前中断
p->chip->enable(irq);
+
+ printk("x: %d r %d t %d \n", irq, irq_reenter, current->ticks);
}
int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname,
root_task.turn = 0;
root_task.sched_cnt = 0;
root_task.sched_keep_cnt = 0;
+ root_task.magic = TASK_MAGIC;
strcpy(root_task.name, "root");
list_add(&root_task.list, &all_tasks);
extern uint32_t disk_handled_cnt;
extern uint32_t disk_inter_cnt;
+void debug_print_all_tasks() {
+ task_union *p = 0;
+ list_head_t *pos = 0, *t = 0;
+ printl(MPL_TASK_TITLE, " NAME STATE TK/PI TURN SCHED KEEP");
+ list_for_each_safe(pos, t, &all_tasks) {
+ p = list_entry(pos, task_union, list);
+ printl(MPL_TASK_0 + p->pid, "%08x%s%4s:%u %s %02u/%02u %-10u %-10u %-10u", p,
+ p->state == TASK_RUNNING ? ">" : " ", p->name, p->pid, task_state(p->state), p->ticks, p->priority,
+ p->turn, p->sched_cnt, p->sched_keep_cnt);
+ }
+}
+
void schedule() {
task_union *root = &root_task;
task_union *sel = 0;
task_union *p = 0;
list_head_t *pos = 0, *t = 0;
+ printk("*");
printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
sel = p;
continue;
}
-
+#if 1
+ // 考察三个量
+ // priority 越大越优先
+ // jiffies 越小越优先
+ // (priority - ticks) 表示已经使用的量,越小越优先
+ int64_t a = sel->jiffies - sel->priority + (sel->priority - sel->ticks);
+ int64_t b = p->jiffies - p->priority + (p->priority - p->ticks);
+ if (a > b) {
+ sel = p;
+ } else if (a == b) {
+ if (sel->priority < p->priority) {
+ sel = p;
+ }
+ }
+#else
if (sel->jiffies < p->jiffies) {
continue;
}
sel = p;
}
}
+#endif
}
task_union *prev = current;
task_union *next = sel != 0 ? sel : root;
next->state = TASK_RUNNING;
+
+#if 1
+ // debug_print_all_tasks();
+#else
+ printl(MPL_TASK_TITLE, " NAME STATE TK/PI TURN SCHED KEEP");
+ list_for_each_safe(pos, t, &all_tasks) {
+ p = list_entry(pos, task_union, list);
+ printl(MPL_TASK_0 + p->pid, "%08x%s%4s:%d %s %02u/%02d %-10u %-10u %-10u", p, next == p ? ">" : " ", p->name,
+ p->pid, task_state(p->state), p->ticks, p->priority, p->turn, p->sched_cnt, p->sched_keep_cnt);
+ }
+#endif
if (prev != next) {
next->sched_cnt++;
-
- printl(MPL_TASK_TITLE, " NAME STATE TK/PI TURN SCHED KEEP");
- list_for_each_safe(pos, t, &all_tasks) {
- p = list_entry(pos, task_union, list);
- printl(MPL_TASK_0 + p->pid, "%08x%s%4s:%d %s %02u/%02d %-10u %-10u %-10u", p, next == p ? ">" : " ",
- p->name, p->pid, task_state(p->state), p->ticks, p->priority, p->turn, p->sched_cnt,
- p->sched_keep_cnt);
- }
-
context_switch(prev, next);
} else {
// 这里可能是的情况是任务把时间片ticks用完了
uint16_t fp = buf[255];
if (fp == vfp) {
- printk("%s verification passed sect %lu fp %04x\n", name, sect_nr, fp);
+ // 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");
current->priority = 19;
while (1) {
- sysc_wait(2);
+ sysc_wait(1);
for (int i = 0; i < 7; i++) {
asm("hlt;");
char *strcat(char *dest, const char *src) {
char *tmp = dest;
while (*dest) dest++;
- while ((*dest++ = *src++) != '\0')
+ while (*dest++ = *src++)
;
return tmp;
}