Browse Source

refactor: add context save and load functions

greatbridf 2 years ago
parent
commit
904883c5e3

+ 1 - 1
include/kernel/interrupt.h

@@ -22,7 +22,7 @@ struct regs_32 {
     uint32_t eax;
 };
 
-struct PACKED irq0_data {
+struct PACKED interrupt_stack {
     struct regs_32 s_regs;
     void* v_eip;
     uint32_t cs;

+ 1 - 1
include/kernel/process.hpp

@@ -40,7 +40,7 @@ public:
 extern process* current_process;
 
 extern "C" void NORETURN init_scheduler();
-void context_switch(irq0_data* intrpt_data);
+void do_scheduling(interrupt_stack* intrpt_data);
 
 #else
 

+ 1 - 10
include/kernel/syscall.hpp

@@ -3,16 +3,7 @@
 #include <types/types.h>
 #include <kernel/interrupt.h>
 
-struct PACKED syscall_stack_data {
-    struct regs_32 s_regs;
-    void* v_eip;
-    uint32_t cs;
-    uint32_t eflags;
-    uint32_t esp;
-    uint32_t ss;
-};
-
 // return value is stored in %eax and %edx
-typedef void (*syscall_handler)(syscall_stack_data* data);
+typedef void (*syscall_handler)(interrupt_stack* data);
 
 void init_syscall(void);

+ 2 - 2
src/kernel/interrupt.cpp

@@ -219,10 +219,10 @@ kill:
     asm_hlt();
 }
 
-extern "C" void irq0_handler(struct irq0_data* d)
+extern "C" void irq0_handler(struct interrupt_stack* d)
 {
     inc_tick();
-    context_switch(d);
+    do_scheduling(d);
     asm_outb(PORT_PIC1_COMMAND, PIC_EOI);
 }
 // keyboard interrupt

+ 44 - 31
src/kernel/process.cpp

@@ -108,7 +108,43 @@ void NORETURN init_scheduler()
     go_user_space(user_space_start);
 }
 
-void context_switch(irq0_data* intrpt_data)
+void thread_context_save(interrupt_stack* int_stack, thread* thd, bool kernel)
+{
+    thd->eflags = int_stack->eflags;
+    thd->eip = int_stack->v_eip;
+    memcpy(&thd->regs, &int_stack->s_regs, sizeof(regs_32));
+    if (!kernel)
+        thd->esp = int_stack->esp;
+}
+
+void thread_context_load(interrupt_stack* int_stack, thread* thd, bool kernel)
+{
+    int_stack->eflags = (thd->eflags | 0x200); // OR $STI
+    int_stack->v_eip = thd->eip;
+    memcpy(&int_stack->s_regs, &thd->regs, sizeof(regs_32));
+    if (!kernel) {
+        int_stack->cs = USER_CODE_SELECTOR;
+        int_stack->ss = USER_DATA_SELECTOR;
+        int_stack->esp = thd->esp;
+    } else {
+        int_stack->cs = KERNEL_CODE_SEGMENT;
+    }
+    current_thread = thd;
+}
+
+void process_context_save(interrupt_stack*, process*)
+{
+}
+
+void process_context_load(interrupt_stack*, process* proc)
+{
+    if (!proc->attr.system)
+        tss.esp0 = (uint32_t)proc->k_esp;
+    asm_switch_pd(mms_get_pd(&proc->mms));
+    current_process = proc;
+}
+
+void do_scheduling(interrupt_stack* intrpt_data)
 {
     if (!is_scheduler_ready)
         return;
@@ -121,38 +157,15 @@ void context_switch(irq0_data* intrpt_data)
         return;
     }
 
-    process* pro = thd->owner;
-    if (current_process != pro) {
-        if (!pro->attr.system) {
-            tss.esp0 = (uint32_t)pro->k_esp;
-        }
-
-        current_process = pro;
-        asm_switch_pd(pro->mms.begin()->pd);
+    process* proc = thd->owner;
+    bool kernel = proc->attr.system;
+    if (current_process != proc) {
+        process_context_save(intrpt_data, current_process);
+        process_context_load(intrpt_data, proc);
     }
 
-    // save current thread info
-    current_thread->eflags = intrpt_data->eflags;
-    current_thread->eip = intrpt_data->v_eip;
-    memcpy(&current_thread->regs, &intrpt_data->s_regs, sizeof(regs_32));
-
-    // load ready thread info
-    intrpt_data->eflags = thd->eflags;
-    intrpt_data->eflags |= 0x200; // sti
-    intrpt_data->v_eip = thd->eip;
-    memcpy(&intrpt_data->s_regs, &thd->regs, sizeof(regs_32));
-
-    if (!pro->attr.system) {
-        // user mode
-        current_thread->esp = intrpt_data->esp;
-
-        intrpt_data->cs = USER_CODE_SELECTOR;
-        intrpt_data->ss = USER_DATA_SELECTOR;
-        intrpt_data->esp = thd->esp;
-    } else {
-        // supervisor mode
-        intrpt_data->cs = KERNEL_CODE_SEGMENT;
-    }
+    thread_context_save(intrpt_data, current_thread, kernel);
+    thread_context_load(intrpt_data, thd, kernel);
 
     ready_thds->erase(ready_thds->begin());
     // check if the thread is ready

+ 4 - 4
src/kernel/syscall.cpp

@@ -4,26 +4,26 @@
 
 syscall_handler syscall_handlers[8];
 
-void _syscall_not_impl(syscall_stack_data* data)
+void _syscall_not_impl(interrupt_stack* data)
 {
     data->s_regs.eax = 0xffffffff;
     data->s_regs.edx = 0xffffffff;
 }
 
-void _syscall_fork(syscall_stack_data* data)
+void _syscall_fork(interrupt_stack* data)
 {
     data->s_regs.eax = 0xfafafafa;
     data->s_regs.edx = 0xfefefefe;
 }
 
-void _syscall_write(syscall_stack_data* data)
+void _syscall_write(interrupt_stack* data)
 {
     tty_print(console, reinterpret_cast<const char*>(data->s_regs.edi));
     data->s_regs.eax = 0;
     data->s_regs.edx = 0;
 }
 
-void _syscall_sleep(syscall_stack_data* data)
+void _syscall_sleep(interrupt_stack* data)
 {
     ++data->s_regs.ecx;
 }