ide_pci_controller_t ide_pci_controller[NR_IDE_CONTROLLER];
void ata_dma_stop(int channel);
-
-void ide_stat_print(ide_pci_controller_t* ide_ctrl) {
- int r = atomic_read(&(ide_ctrl->request_cnt));
- int i = atomic_read(&(ide_ctrl->irq_cnt));
- int c = atomic_read(&(ide_ctrl->consumed_cnt));
- int channel = ide_ctrl->channel;
- printlxy(MPL_IDE0 + channel, MPO_IDE, "IDE%d req %u irq %u consumed %u", channel, r, i, c);
-}
-
void ide_irq_bh_handler(void* arg) {
int channel = (int)arg;
//
atomic_inc(&ide_ctrl->irq_cnt);
- //
- ide_stat_print(ide_ctrl);
-
// 之前这里是用up()来唤醒磁盘任务
// 但在中断的底半处理,不应该切换任务,因为会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务
// 所以就移除了up()里的 schedule()
pci->intr_line, pci->vendor, pci->device, pci->progif, pci_get_info(pci->classcode, pci->progif));
// printk("found pci vendor %04x device %04x class %04x intr %d progif: %x\n", pci->vendor, pci->device,
// pci->classcode, pci->intr_line, pci->progif);
- // printl(17, "found pci vendor %04x device %04x class %04x intr %d", pci->vendor, pci->device,
- // pci->classcode,
- // pci->intr_line);
ide_pci_init(pci);
// while (1) asm("cli;hlt;");
}
extern ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT];
ide_drive_t* ide_get_drive(dev_t dev);
-void ide_stat_print(ide_pci_controller_t* ide_ctrl);
extern tty_t* const debug_tty;
extern void tty_switch_to_next();
+uint64_t kbd_irq_cnt = 0;
void kbd_debug(uint8_t scan_code) {
- static unsigned long kbd_cnt = 0;
- // printl(MPL_KEYBOARD, "keyboard irq: %d scan code %02x", kbd_cnt++, scan_code);
- printlxy(MPL_IRQ, MPO_KEYBOARD, "KBD: %02x %d", scan_code, kbd_cnt++);
+ kbd_irq_cnt++;
if (scan_code == 0x01) { // Esc
// reboot();
// monitor print offset
enum {
- MPO_CLOCK = 1,
- MPO_HPET = 28,
+ MPO_HPET = 1,
+ MPO_AP_CLOCK = 28,
MPO_KEYBOARD = 48,
MPO_IDE = 1,
};
void* kzalloc(size_t size, gfp_t gfpflags);
void kfree(void* addr);
-#define panic(msg, ...) \
- do { \
- asm("cli;"); \
- printl(MPL_DEBUG, "PANIC:" msg " %s %s %d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \
- printk("PANIC:" msg " %s %s %d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \
- asm("hlt"); \
- } while (0);
-
extern char etext, edata, end;
#define cli() asm volatile("cli")
#define DISABLE_IDE 1
+#define panic(msg, ...) \
+ do { \
+ asm("cli;"); \
+ printk("PANIC:" msg " %s %s %d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \
+ asm("hlt"); \
+ } while (0);
+
#endif //_SYSTEM_H
hpet_disable();
// 只要不hpet_enable, HPET的计数器就不会启动
- hpet_prepare_calibration(timn, 2 /*hz*/);
+ hpet_prepare_calibration(timn, 97 /*hz*/);
//
hpet_enable();
uint32_t ap_cpuid = lapic->get_lapic_id();
printk("AP CPU id: %d\n", ap_cpuid);
- system.ap_cpuid = ap_cpuid;
+ system.ap_cpuid = ap_cpuid; // 这之后不能再printk了
asm("sti;");
+ const char* title = "KERNEL MONITOR";
+ printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title);
+
while (1) {
asm("hlt;");
}
}
-void do_ap_lapic_irq_handler() {
- uint8_t* p = (uint8_t*)0xC00B8002;
- *p = *p == ' ' ? 'E' : ' ';
- system.lapic->write(LAPIC_EOI, 0);
+bool ap_ready() {
+ return system.ap_cpuid != 0;
}
+uint64_t ap_pit_ticks = 0;
void do_ap_pit_irq_handler() {
uint8_t* p = (uint8_t*)0xC00B8004;
*p = *p == ' ' ? 'R' : ' ';
+ ap_pit_ticks++;
+
system.lapic->write(LAPIC_EOI, 0);
}
panic("AP unexpected irq\n");
}
-bool ap_ready() {
- return system.ap_cpuid != 0;
+uint64_t ap_lapic_ticks = 0;
+void do_ap_lapic_irq_handler() {
+ uint8_t* p = (uint8_t*)0xC00B8002;
+ *p = *p == ' ' ? 'E' : ' ';
+
+ //
+ extern volatile uint64_t jiffies;
+ extern volatile uint64_t hpet_ticks; // jiffies 和 hpet_ticks 是同一个东西
+ printlxy(MPL_IRQ, MPO_HPET, "HPET: %lu", jiffies);
+
+ //
+ extern volatile uint8_t scan_code;
+ extern volatile uint64_t kbd_irq_cnt;
+ printlxy(MPL_IRQ, MPO_KEYBOARD, "KBD: %02x %lu", scan_code, kbd_irq_cnt);
+
+ //
+ printlxy(MPL_IRQ, MPO_AP_CLOCK, "AP: %lu", ap_lapic_ticks);
+
+ //
+ void print_all_tasks();
+ print_all_tasks();
+
+ //
+ // void print_all_ides();
+ // print_all_ides();
+
+ ap_lapic_ticks++;
+
+ system.lapic->write(LAPIC_EOI, 0);
+}
+
+#include <task.h>
+const char* task_state(unsigned int state) {
+ static const char s[][8] = {
+ " ERROR", "\x10\x07RUN\x07", " READY", " WAIT ", " INIT ", " EXIT ",
+ };
+
+ if (state >= TASK_END) {
+ state = TASK_UNUSED;
+ }
+
+ return s[state];
+}
+void print_all_tasks() {
+ extern task_t* monitor_tasks[];
+
+ printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN");
+
+ for (int i = 0; i < 10; i++) {
+ task_t* p = monitor_tasks[i];
+
+ if (p == NULL) {
+ continue;
+ }
+
+ printl(MPL_TASK_0 + p->pid, "a%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u",
+ p, //
+ p->name, //
+ p->pid, //
+ task_state(p->state), //
+ p->ticks, //
+ p->priority, //
+ p->reason, //
+ p->sched_cnt, //
+ p->sched_keep_cnt, //
+ p->turn //
+ );
+ }
+}
+
+#include <ide.h>
+extern ide_pci_controller_t ide_pci_controller[];
+void ide_stat_print(ide_pci_controller_t* ide_ctrl) {
+ assert(ide_ctrl != NULL);
+ assert(ide_ctrl >= ide_pci_controller);
+ assert(ide_ctrl < (ide_pci_controller + NR_IDE_CONTROLLER));
+ int r = atomic_read(&(ide_ctrl->request_cnt));
+ int i = atomic_read(&(ide_ctrl->irq_cnt));
+ int c = atomic_read(&(ide_ctrl->consumed_cnt));
+ int channel = ide_ctrl->channel;
+ printlxy(MPL_IDE0 + channel, MPO_IDE, "IDE%d req %u irq %u consumed %u", channel, r, i, c);
+}
+
+void print_all_ides() {
+ ide_stat_print(&ide_pci_controller[0]);
+ ide_stat_print(&ide_pci_controller[1]);
}
// ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (dst_cpuid << 56));
// 把8253/8254的中断通过IOAPIC转发到CPU1的0号中断
ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (1ULL << 56));
+ ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (1ULL << 56) | 0x10000);
// 把键盘中断通过IOAPIC转发到CPU0的1号中断
ioapic_rte_write(IOAPIC_RTE(1), 0x20 + 1 | (dst_cpuid << 56));
// irq_set_chip(0x00, &ioapic_chip); // ap不需要这个
void assert_fail(char* exp, char* file, unsigned int line, const char* func) {
asm("cli");
- printl(MPL_DEBUG, "%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp);
printk("%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp);
while (1) {
asm("hlt;");
return jiffies;
}
-void debug_print_all_tasks();
-
-void dump_irq_nr_stack();
void clk_bh_handler(void* arg);
extern volatile bool enable_clock_irq_delay;
void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
- // if (jiffies % 100 == 0) {
- // printl(MPL_CLOCK, "clock irq: %d", jiffies);
- printlxy(MPL_IRQ, MPO_CLOCK, "CLK: %d", jiffies);
- // printk("CLK irq %d\n", jiffies);
- // }
-
jiffies++;
current->jiffies = jiffies;
#include <page.h>
#include <sched.h>
-extern void ret_from_fork_user();
-extern void ret_from_fork_krnl();
extern pid_t get_next_pid();
extern list_head_t all_tasks;
continue;
}
-#if 1
pde_dst[i] = pde_src[i] & (~PDE_RW);
-#else
- // 这里不用再为每个PDE拷贝一次PageTable,只需要拷贝PageDirectory并将其低于768的写权限去掉
- // 同时需要修改缺页异常do_page_fault的逻辑
- if (PAGE_ALIGN(spde) != 0) {
- dpde = page2va(alloc_one_page(0));
- assert(dpde != 0);
- memset((void*)dpde, 0, PAGE_SIZE);
- dpde = PAGE_FLAGS(spde) | (unsigned long)va2pa(dpde);
- } else {
- pde_dst[i] = 0;
- continue;
- }
- pde_dst[i] = dpde;
-
- pte_t* pte_src = pa2va(PAGE_ALIGN(spde));
- pte_t* pte_dst = pa2va(PAGE_ALIGN(dpde));
- for (j = 0; j < PAGE_PTE_CNT; ++j) {
- pte_src[j] &= ~PAGE_WR;
- pte_dst[j] = pte_src[j];
-
- if (pte_src[j] == 0) {
- continue;
- }
- printk("----pde[%u] pte_src[%u] %08x\n", i, j, pte_src[j]);
- page_t* page = pa2page(pte_src[j]);
- page->count++;
- }
-#endif
}
pt_regs_t* child_regs = ((pt_regs_t*)(TASK_SIZE + (unsigned long)tsk)) - 1;
tsk->state = TASK_READY;
+ void add_task_for_monitor(task_t * tsk);
+ add_task_for_monitor(tsk);
+
return (int)tsk->pid;
fork_child:
uint32_t hpet_clock_period = 0;
uint64_t hpet_clock_mhz_freq = 0; // 32位系统不支持64位除法,所以用MHz为单位
-static uint64_t hpet_ticks = 0;
-void hpet0_bh_handler() {
- // hpet_ticks++;
- printlxy(MPL_IRQ, MPO_HPET, "HPET: %lu", hpet_ticks);
-}
+uint64_t hpet_ticks = 0;
void hpet0_irq_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
hpet_ticks++;
uint8_t* p = (uint8_t*)0xC00B8000;
*p = *p == ' ' ? 'K' : ' ';
- add_irq_bh_handler(hpet0_bh_handler, NULL);
-
system.lapic->write(LAPIC_EOI, 0);
}
panic("invalid irq %d\n", irq);
}
-#if 0
- assert(1 == irq);
- uint8_t b = inb(0x60);
- printk("irq %d b %02x\n", irq, b);
- // write_msr32(0x80b, 0);
- system.lapic->write(0xB0, 0);
- // vaddr_t apic_virt_base_addr = fixid_to_vaddr(FIX_LAPIC_BASE);
- // apic_virt_base_addr += 0xB0;
- // *((volatile uint32_t*)apic_virt_base_addr) = 0x0;
-#endif
-#if 0
- // 检查IMCR
- outb(0x22, 0x70);
- uint8_t imcr = inb(0x23);
- printk("IMCR: 0x%02x (bit0=%s, bit1=%s)\n", imcr, (imcr & 0x01) ? "APIC" : "PIC",
- (imcr & 0x02) ? "PIC masked" : "PIC active");
-
- // 检查8259A状态
- uint8_t pic1_imr = inb(0x21);
- uint8_t pic2_imr = inb(0xA1);
- printk("8259A IMR: Master=0x%02x, Slave=0x%02x\n", pic1_imr, pic2_imr);
-
- // 检查IOAPIC是否响应
- volatile uint32_t* ioapic = (volatile uint32_t*)system.ioapic_map->io_reg_sel;
- ioapic[0] = 0x01; // 选择版本寄存器
- uint32_t version = ioapic[4];
- printk("IOAPIC version: 0x%08x\n", version);
-#endif
#if 1
irq_desc_t* p = irq_desc + irq;
irq_action_t* action = p->action;
assert(reenter <= 1);
// TODO 判断打断的是否是内核态代码
-#if 0
- if (0x00 == irq) {
- if ((clk_irq_cnt++ & 0xFU) != 0) {
- unsigned long esp;
- asm("movl %%esp, %%eax" : "=a"(esp));
- printl(MPL_CURRENT, "current %08x %-6s cr3 %08x reenter %d:%u esp %08x ticks %u", current, current->name,
- current->cr3, reenter, reenter_count, esp, current->ticks);
- }
- }
-#endif
while (action && action->handler) {
action->handler(irq, regs, action->dev_id);
// 这里可能存在有部分没处理完
}
- void debug_print_all_tasks();
#if ENABLE_CLOCK_IRQ_WAIT
- debug_print_all_tasks();
if (irq_bh_actions == NULL) {
asm("hlt;");
}
#else
if (jiffies < end) {
- debug_print_all_tasks();
+ // debug_print_all_tasks();
}
#endif
}
# 纯消耗CPU时间
- movl $0x0F0F0F0F, %ecx
+ movl $0xFF0F0F0F, %ecx
1:
loop 1b
return p;
}
-const char* task_state(unsigned int state) {
- static const char s[][8] = {
- " ERROR", "\x10\x07RUN\x07", " READY", " WAIT ", " INIT ", " EXIT ",
- };
-
- if (state >= TASK_END) {
- state = TASK_UNUSED;
- }
-
- return s[state];
-}
-
-void debug_print_all_tasks() {
- task_t* p = 0;
- list_head_t *pos = 0, *t = 0;
- printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN");
- list_for_each_safe(pos, t, &all_tasks) {
- p = list_entry(pos, task_t, list);
- printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u", p, p->name, p->pid,
- task_state(p->state), p->ticks, p->priority, p->reason, p->sched_cnt, p->sched_keep_cnt, p->turn);
- }
-}
-
void schedule() {
task_t* root = &root_task;
task_t* sel = 0;
task_t* p = list_entry(current->list.next, task_t, list);
p->state = (p->state == TASK_READY) ? TASK_WAIT : TASK_READY;
}
+
+task_t* monitor_tasks[1024] = {&root_task, 0};
+void add_task_for_monitor(task_t* tsk) {
+ assert(tsk != NULL);
+ int id = tsk->pid;
+ monitor_tasks[id] = tsk;
+}
cnsl_init();
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
- const char* title = "KERNEL MONITOR";
- printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title);
-
setup_fs();
setup_tasks();
// ap 启动需要用到 hpet来校准
wait_ap_boot();
- hpet_init_timer0(1);
+ hpet_init_timer0(101);
#if !DISABLE_IDE
void ide_init();
int sysc_debug(unsigned int v) {
static unsigned int cnt = 0;
- printl(MPL_DEBUG, "task debug syscall %u value %08x", cnt++, v);
+ cnt++;
return 0;
}
printk("IDE status %02X error for drv %u pos %lu count %u\n", ide_ctrl->status, drvid, pos, r->count);
ret = -1;
}
-
- ide_stat_print(ide_ctrl);
}
// 读数据