From 75ec633805db108bfddb6454ff7f8d812475feaf Mon Sep 17 00:00:00 2001 From: dzwdz Date: Mon, 11 Apr 2022 23:29:30 +0200 Subject: kernel: implement `cpu_pause()` in assembly, remove `irq_interrupt_flag()` --- src/kernel/arch/generic.h | 3 +++ src/kernel/arch/i386/boot.s | 9 +++++++++ src/kernel/arch/i386/interrupts/irq.c | 5 ----- src/kernel/arch/i386/interrupts/irq.h | 2 -- src/kernel/arch/i386/sysenter.c | 3 --- src/kernel/arch/i386/sysenter.s | 2 ++ src/kernel/proc.c | 7 +++---- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h index fcc228e..01a3826 100644 --- a/src/kernel/arch/generic.h +++ b/src/kernel/arch/generic.h @@ -18,6 +18,9 @@ void halt_cpu(void); __attribute__((noreturn)) void cpu_shutdown(void); +/** on x86: waits for an IRQ */ +void cpu_pause(void); + // src/arch/i386/sysenter.s _Noreturn void sysexit(struct registers); diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index ea31aa1..24c076f 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -23,3 +23,12 @@ halt_cpu: cli 1: hlt jmp 1b + + +.global cpu_pause +.type cpu_pause, @function +cpu_pause: + sti + hlt + cli + ret diff --git a/src/kernel/arch/i386/interrupts/irq.c b/src/kernel/arch/i386/interrupts/irq.c index 7b8c166..5918169 100644 --- a/src/kernel/arch/i386/interrupts/irq.c +++ b/src/kernel/arch/i386/interrupts/irq.c @@ -31,8 +31,3 @@ void irq_eoi(uint8_t line) { if (line >= 8) port_out8(PIC2, 0x20); } - -void irq_interrupt_flag(bool flag) { - if (flag) asm("sti" : : : "memory"); - else asm("cli" : : : "memory"); -} diff --git a/src/kernel/arch/i386/interrupts/irq.h b/src/kernel/arch/i386/interrupts/irq.h index 73d4af2..f523154 100644 --- a/src/kernel/arch/i386/interrupts/irq.h +++ b/src/kernel/arch/i386/interrupts/irq.h @@ -4,5 +4,3 @@ void irq_init(void); void irq_eoi(uint8_t line); - -void irq_interrupt_flag(bool flag); diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c index 1aee254..5712ee3 100644 --- a/src/kernel/arch/i386/sysenter.c +++ b/src/kernel/arch/i386/sysenter.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -22,8 +21,6 @@ _Noreturn void sysenter_stage2(void) { regs->esp = (userptr_t) regs->ecx; // fix them up regs->eip = (userptr_t) regs->edx; - irq_interrupt_flag(false); - val = _syscall(regs->eax, regs->ebx, regs->esi, regs->edi, (uintptr_t)regs->ebp); if (process_current->state == PS_RUNNING) { // TODO move to _syscall() diff --git a/src/kernel/arch/i386/sysenter.s b/src/kernel/arch/i386/sysenter.s index db65a8c..ade69ec 100644 --- a/src/kernel/arch/i386/sysenter.s +++ b/src/kernel/arch/i386/sysenter.s @@ -48,6 +48,8 @@ sysenter_setup: ret sysenter_stage1: + cli /* prevent random IRQs in the middle of kernel code */ + // disable paging // I don't want to damage any of the registers passed in by the user, // so i'm using ESP as a temporary register. At this point there's nothing diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 1f012fa..944f5b9 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -6,7 +6,6 @@ #include #include #include -#include // TODO move irq stuff to arch/generic #include // TODO struct process *process_first; @@ -86,13 +85,13 @@ _Noreturn void process_idle(void) { for (;;) { for (size_t i = 0; i < len; i++) { if (procs[i]->waits4irq.ready()) { + /* if this is entered during the first iteration, it indicates a + * kernel bug. this should be logged. TODO? */ vfs_root_handler(&procs[i]->waits4irq.req); // TODO this should be a function pointer too process_switch_any(); } } - irq_interrupt_flag(true); - asm("hlt" ::: "memory"); // TODO move to irq.c - irq_interrupt_flag(false); + cpu_pause(); } } -- cgit v1.2.3