Selaa lähdekoodia

Kernel: Implement entry code for x86_64 interrupts

With this fixed we can now properly handle interrupts (e.g. timer
interrupts) on x86_64.
Gunnar Beutner 4 vuotta sitten
vanhempi
commit
076692b1ef
2 muutettua tiedostoa jossa 31 lisäystä ja 3 poistoa
  1. 2 2
      Kernel/Arch/x86/RegisterState.h
  2. 29 1
      Kernel/Arch/x86/x86_64/InterruptEntry.cpp

+ 2 - 2
Kernel/Arch/x86/RegisterState.h

@@ -47,11 +47,11 @@ struct [[gnu::packed]] RegisterState {
     FlatPtr r14;
     FlatPtr r15;
 #endif
-    u16 exception_code;
-    u16 isr_number;
 #if ARCH(X86_64)
     u32 padding;
 #endif
+    u16 exception_code;
+    u16 isr_number;
 #if ARCH(I386)
     FlatPtr eip;
 #else

+ 29 - 1
Kernel/Arch/x86/x86_64/InterruptEntry.cpp

@@ -12,7 +12,35 @@
 asm(
     ".globl interrupt_common_asm_entry\n"
     "interrupt_common_asm_entry: \n"
-    "    hlt \n" // FIXME
+    // add the padding field in RegisterState
+    "    subq $4, %rsp\n"
+    "    movl $0, 0(%rsp)\n"
+    // save all the other registers
+    "    pushq %r15\n"
+    "    pushq %r14\n"
+    "    pushq %r13\n"
+    "    pushq %r12\n"
+    "    pushq %r11\n"
+    "    pushq %r10\n"
+    "    pushq %r9\n"
+    "    pushq %r8\n"
+    "    pushq %rax\n"
+    "    pushq %rcx\n"
+    "    pushq %rdx\n"
+    "    pushq %rbx\n"
+    "    pushq %rsp\n"
+    "    pushq %rbp\n"
+    "    pushq %rsi\n"
+    "    pushq %rdi\n"
+    "    pushq %rsp \n" /* set TrapFrame::regs */
+    "    subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n"
+    "    subq $0x8, %rsp\n" /* align stack */
+    "    lea 0x8(%rsp), %rdi \n"
+    "    cld\n"
+    "    call enter_trap \n"
+    "    lea 0x8(%rsp), %rdi \n"
+    "    call handle_interrupt \n"
+    "    addq $0x8, %rsp\n" /* undo alignment */
     ".globl common_trap_exit \n"
     "common_trap_exit: \n"
     // another thread may have handled this trap at this point, so don't