diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index c32d5e55..10f25d61 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -482,8 +482,18 @@ void do_IRQ(struct pt_regs *rsp, ul number) else if (number > 0x80) { - printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number); + //printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number); apic_local_apic_edge_ack(number); + if (number == 0xc8) // 来自BSP的HPET中断消息 + { + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2; + ++(current_pcb->virtual_runtime); + + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) + current_pcb->flags |= PROC_NEED_SCHED; + + //printk_color(RED, BLACK, "CPU_exec_task_jiffies:%d current_pcb = %#018lx\t current_pcb->thread=%#018lx\n", sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies, (ul)current_pcb, (ul)current_pcb->thread); + } } else { @@ -501,7 +511,7 @@ void do_IRQ(struct pt_regs *rsp, ul number) kBUG("current_pcb->preempt_count<0! pid=%d", current_pcb->pid); // should not be here // 检测当前进程是否可被调度 - if (current_pcb->flags & PROC_NEED_SCHED) + if (current_pcb->flags & PROC_NEED_SCHED && proc_current_cpu_id == 1) { sched_cfs(); } diff --git a/kernel/driver/timers/HPET/HPET.c b/kernel/driver/timers/HPET/HPET.c index 16e00865..b3647bb1 100644 --- a/kernel/driver/timers/HPET/HPET.c +++ b/kernel/driver/timers/HPET/HPET.c @@ -6,6 +6,7 @@ #include #include #include +#include static struct acpi_HPET_description_table_t *hpet_table; static uint64_t HPET_REG_BASE = 0; @@ -50,11 +51,16 @@ hardware_intr_controller HPET_intr_controller = void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { - //printk("(HPET)"); + // printk("(HPET)"); switch (param) { case 0: // 定时器0中断 ++timer_jiffies; + + // 将HEPT中断消息转发到ap:1处理器 + ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0xc8, + ICR_APIC_FIXED, ICR_No_Shorthand, true, 1); + // 若当前时间比定时任务的时间间隔大,则进入中断下半部 if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies) set_softirq_status(TIMER_SIRQ); @@ -63,20 +69,22 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { case 0: case 1: - --sched_cfs_ready_queue.cpu_exec_proc_jiffies; + --sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies; ++current_pcb->virtual_runtime; break; case 2: default: - sched_cfs_ready_queue.cpu_exec_proc_jiffies -= 2; + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2; current_pcb->virtual_runtime += 2; break; } - if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0) + /* 由于目前只有BSP处理器会收到HPET中断,因此这里只会标记BSP处理器的进程需要调度 + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) { current_pcb->flags |= PROC_NEED_SCHED; } + */ break; @@ -155,8 +163,6 @@ int HPET_init() // 使用I/O APIC 的IRQ2接收hpet定时器0的中断 apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0); - - *(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0; io_mfence(); *(uint64_t *)(HPET_REG_BASE + TIM0_CONF) = 0x004c; // 设置定时器0为周期定时,边沿触发,投递到IO APIC的2号引脚(这里有点绕,写的是8259的引脚号,但是因为禁用了8259,因此会被路由到IO APIC的2号引脚) @@ -166,8 +172,6 @@ int HPET_init() rtc_get_cmos_time(&rtc_now); - - kinfo("HPET Initialized."); *(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位 io_mfence(); diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index 5debb717..5f83d1cf 100644 --- a/kernel/exception/trap.c +++ b/kernel/exception/trap.c @@ -198,7 +198,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) __asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory"); - kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx\n",error_code , regs->rsp , regs->rip); + kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx CPU:%d\n",error_code , regs->rsp , regs->rip, proc_current_cpu_id); if(!(error_code & 0x01)) printk_color(RED,BLACK,"Page Not-Present,\t"); diff --git a/kernel/main.c b/kernel/main.c index 0b12aaf5..5ac73e97 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -132,7 +132,7 @@ void system_initialize() syscall_init(); // 再初始化进程模块。顺序不能调转 sched_init(); - kdebug("sched_cfs_ready_queue.cpu_exec_proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies); + timer_init(); smp_init(); @@ -146,15 +146,12 @@ void system_initialize() // test_mm(); - process_init(); + //process_init(); HPET_init(); - while(1) - { - printk_color(ORANGE, BLACK, "i\n"); - } + } //操作系统内核从这里开始执行 diff --git a/kernel/process/process.c b/kernel/process/process.c index f4833036..ab7f470b 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -349,7 +349,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned // 将当前进程的pcb复制到新的pcb内 *tsk = *current_pcb; - + //kdebug("current_pcb->flags=%#010lx", current_pcb->flags); // 将进程加入循环链表 @@ -385,7 +385,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned else kdebug("is kernel proc."); - kdebug("ret_from_system_call=%#018lx", (ul)ret_from_system_call); + tsk->state = PROC_RUNNING; diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index c7841213..afaeeaab 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -1,6 +1,8 @@ #include "sched.h" #include +struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 + /** * @brief 从就绪队列中取出PCB * @@ -8,16 +10,16 @@ */ struct process_control_block *sched_cfs_dequeue() { - if (list_empty(&sched_cfs_ready_queue.proc_queue.list)) + if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) { kdebug("list empty"); return &initial_proc_union.pcb; } - struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list); + struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list); list_del(&proc->list); - --sched_cfs_ready_queue.count; + --sched_cfs_ready_queue[proc_current_cpu_id].count; return proc; } @@ -28,10 +30,10 @@ struct process_control_block *sched_cfs_dequeue() */ void sched_cfs_enqueue(struct process_control_block *pcb) { - struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list); + struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list); if (proc == &initial_proc_union.pcb) return; - if ((list_empty(&sched_cfs_ready_queue.proc_queue.list)) == 0) + if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0) { while (proc->virtual_runtime < pcb->virtual_runtime) { @@ -39,7 +41,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb) } } list_append(&proc->list, &pcb->list); - ++sched_cfs_ready_queue.count; + ++sched_cfs_ready_queue[proc_current_cpu_id].count; } /** @@ -58,17 +60,17 @@ void sched_cfs() if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理 sched_cfs_enqueue(current_pcb); - if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0) + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) { switch (proc->priority) { case 0: case 1: - sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count; + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count; break; case 2: default: - sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2; + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2; break; } } @@ -79,20 +81,20 @@ void sched_cfs() // kdebug("not switch."); sched_cfs_enqueue(proc); - if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0) + if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0) { switch (proc->priority) { case 0: case 1: - sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count; - //sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count; + // sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; break; case 2: default: - //sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; + // sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; - sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2; + sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2; break; } } @@ -105,9 +107,13 @@ void sched_cfs() */ void sched_init() { - memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t)); - list_init(&sched_cfs_ready_queue.proc_queue.list); - sched_cfs_ready_queue.count = 1; // 因为存在IDLE进程,因此为1 - sched_cfs_ready_queue.cpu_exec_proc_jiffies = 8; - sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff; + memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t) * MAX_CPU_NUM); + for (int i = 0; i < MAX_CPU_NUM; ++i) + { + + list_init(&sched_cfs_ready_queue[i].proc_queue.list); + sched_cfs_ready_queue[i].count = 1; // 因为存在IDLE进程,因此为1 + sched_cfs_ready_queue[i].cpu_exec_proc_jiffies = 5; + sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff; + } } \ No newline at end of file diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 31a836e6..6a925429 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -3,6 +3,7 @@ #include #include +// @todo: 用红黑树重写cfs的队列 struct sched_queue_t { long count; // 当前队列中的数量 @@ -10,8 +11,8 @@ struct sched_queue_t struct process_control_block proc_queue; }; -// @todo: 用红黑树重写cfs的队列 -struct sched_queue_t sched_cfs_ready_queue; // 就绪队列 + +extern struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 /** * @brief 调度函数 diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c index c29b3144..03fc270b 100644 --- a/kernel/smp/smp.c +++ b/kernel/smp/smp.c @@ -34,7 +34,7 @@ void smp_init() // 设置多核IPI中断门 for (int i = 200; i < 210; ++i) - set_intr_gate(i, 2, SMP_interrupt_table[i - 200]); + set_intr_gate(i, 0, SMP_interrupt_table[i - 200]); memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM); @@ -117,14 +117,41 @@ void smp_ap_start() kdebug("current cpu = %d", current_starting_cpu); apic_init_ap_core_local_apic(); + + // ============ 为ap处理器初始化IDLE进程 ============= + memset(current_pcb, 0, sizeof(struct process_control_block)); + + current_pcb->state = PROC_RUNNING; + current_pcb->flags = PF_KTHREAD; + current_pcb->mm = &initial_mm; + + list_init(¤t_pcb->list); + current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR; + current_pcb->priority = 2; + current_pcb->virtual_runtime = 0; + + current_pcb->thread = (struct thread_struct *)(current_pcb + 1); // 将线程结构体放置在pcb后方 + current_pcb->thread->rbp = _stack_start; + current_pcb->thread->rsp = _stack_start; + current_pcb->thread->fs = KERNEL_DS; + current_pcb->thread->gs = KERNEL_DS; + current_pcb->cpu_id = current_starting_cpu; + + initial_proc[proc_current_cpu_id] = current_pcb; + load_TR(10 + current_starting_cpu * 2); - sti(); // kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table)); - memset(current_pcb, 0, sizeof(struct process_control_block)); spin_unlock(&multi_core_starting_lock); - - int a = 1 / 0; + current_pcb->preempt_count = 0; + sti(); + + if(proc_current_cpu_id == 1) + process_init(); + while(1) + { + printk_color(BLACK, WHITE, "CPU:%d IDLE process.\n", proc_current_cpu_id); + } while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt hlt(); } \ No newline at end of file