SMP Booting, APIC, and IRQs
[akaros.git] / kern / trapentry.S
index 80c5f11..a4cc312 100644 (file)
        .long name;                                                     \
        .long num
 
+/* Same as NOEC, but for IRQs instead.  num is the ISR number it is mapped to */
+#define IRQ_HANDLER(name, num)                 \
+       .text;                                                          \
+       .globl name;                                            \
+       .type name, @function;                          \
+       .align 2;                                                       \
+       name:                                                           \
+       pushl $0;                                                       \
+       pushl $(num);                                           \
+       jmp _allirqs;                                           \
+       .data;                                                          \
+       .long name;                                                     \
+       .long num
+
 .data
-.globl trap_tbl;
+.globl trap_tbl
 trap_tbl:
 
 /*
  * Lab 3: Your code here for generating entry points for the different traps.
  */
-TRAPHANDLER_NOEC(ISR_divide_error, T_DIVIDE);
-TRAPHANDLER_NOEC(ISR_debug_exceptions, T_DEBUG);
-/* NMI is int 2 */
-TRAPHANDLER_NOEC(ISR_breakpoint, T_BRKPT);
-TRAPHANDLER_NOEC(ISR_overflow, T_OFLOW);
-TRAPHANDLER_NOEC(ISR_bounds_check, T_BOUND);
-TRAPHANDLER_NOEC(ISR_invalid_opcode, T_ILLOP);
-TRAPHANDLER_NOEC(ISR_device_not_available, T_DEVICE);
+TRAPHANDLER_NOEC(ISR_divide_error, T_DIVIDE)
+TRAPHANDLER_NOEC(ISR_debug_exceptions, T_DEBUG)
+TRAPHANDLER_NOEC(ISR_NMI, T_NMI)
+TRAPHANDLER_NOEC(ISR_breakpoint, T_BRKPT)
+TRAPHANDLER_NOEC(ISR_overflow, T_OFLOW)
+TRAPHANDLER_NOEC(ISR_bounds_check, T_BOUND)
+TRAPHANDLER_NOEC(ISR_invalid_opcode, T_ILLOP)
+TRAPHANDLER_NOEC(ISR_device_not_available, T_DEVICE)
 /* supposedly, DF generates an error code, but the one time we've had a DF so
- * far, it didn't eventually, this should probably be handled with a task gate
+ * far, it didn't.  eventually, this should probably be handled with a task gate
+ * it might have pushed a 0, but just the rest of the stack was corrupt
  */
-TRAPHANDLER_NOEC(ISR_double_fault, T_DBLFLT);
+TRAPHANDLER_NOEC(ISR_double_fault, T_DBLFLT)
 /* 9 reserved */
-TRAPHANDLER(ISR_invalid_TSS, T_TSS);
-TRAPHANDLER(ISR_segment_not_present, T_SEGNP);
-TRAPHANDLER(ISR_stack_exception, T_STACK);
-TRAPHANDLER(ISR_general_protection_fault, T_GPFLT);
-TRAPHANDLER(ISR_page_fault, T_PGFLT);
+TRAPHANDLER(ISR_invalid_TSS, T_TSS)
+TRAPHANDLER(ISR_segment_not_present, T_SEGNP)
+TRAPHANDLER(ISR_stack_exception, T_STACK)
+TRAPHANDLER(ISR_general_protection_fault, T_GPFLT)
+TRAPHANDLER(ISR_page_fault, T_PGFLT)
 /* 15 reserved */
-TRAPHANDLER_NOEC(ISR_floating_point_error, T_FPERR);
-TRAPHANDLER(ISR_alignment_check, T_ALIGN);
-TRAPHANDLER_NOEC(ISR_machine_check, T_MCHK);
-TRAPHANDLER_NOEC(ISR_simd_error, T_SIMDERR);
+TRAPHANDLER_NOEC(ISR_floating_point_error, T_FPERR)
+TRAPHANDLER(ISR_alignment_check, T_ALIGN)
+TRAPHANDLER_NOEC(ISR_machine_check, T_MCHK)
+TRAPHANDLER_NOEC(ISR_simd_error, T_SIMDERR)
+/* 20 - 31 reserved */
+IRQ_HANDLER(IRQ0, 32)
+IRQ_HANDLER(IRQ1, 33)
+IRQ_HANDLER(IRQ2, 34)
+IRQ_HANDLER(IRQ3, 35)
+IRQ_HANDLER(IRQ4, 36)
+IRQ_HANDLER(IRQ5, 37)
+IRQ_HANDLER(IRQ6, 38)
+IRQ_HANDLER(IRQ7, 39)
+IRQ_HANDLER(IRQ8, 40)
+IRQ_HANDLER(IRQ9, 41)
+IRQ_HANDLER(IRQ10, 42)
+IRQ_HANDLER(IRQ11, 43)
+IRQ_HANDLER(IRQ12, 44)
+IRQ_HANDLER(IRQ13, 45)
+IRQ_HANDLER(IRQ14, 46)
+IRQ_HANDLER(IRQ15, 47)
 
-TRAPHANDLER_NOEC(ISR_syscall, T_SYSCALL);
+TRAPHANDLER_NOEC(ISR_syscall, T_SYSCALL)
 /* Make sure default is last!! */
-TRAPHANDLER_NOEC(ISR_default, T_DEFAULT);
+TRAPHANDLER_NOEC(ISR_default, T_DEFAULT)
 
 .data
-.globl trap_tbl_end;
+.globl trap_tbl_end
 trap_tbl_end:
 
 .text
-/*
- * Lab 3: Your code here for _alltraps
- */
 _alltraps:
-       pushl %ds;
-       pushl %es;
-       pushal;
-       movw $GD_KD, %ax; /* data segments aren't accessible by default */
-       movw %ax, %ds;
-       movw %ax, %es;
-       pushl %esp;
-       call trap;
-       popl %esp;
-       popal;
-       popl %es;
-       popl %ds;
-       addl $0x8, %esp; /* skip trapno and err */
-       iret;
+       cld
+       pushl %ds
+       pushl %es
+       pushal
+       movw $GD_KD, %ax                # data segments aren't accessible by default
+       movw %ax, %ds
+       movw %ax, %es
+       pushl %esp
+       movl $0, %ebp                   # so we can backtrace to this point
+       call trap
+       popl %esp
+       popal
+       popl %es
+       popl %ds
+       addl $0x8, %esp                 # skip trapno and err
+       iret
+
+/* will need to think about when we reenable interrupts.  right now, iret does it,
+ * if the previous EFLAGS had interrupts enabled 
+ */
+_allirqs:
+       cld
+       pushl %ds
+       pushl %es
+       pushal
+       movw $GD_KD, %ax                # data segments aren't accessible by default
+       movw %ax, %ds
+       movw %ax, %es
+       pushl %esp
+       movl $0, %ebp                   # so we can backtrace to this point
+       call irq_handler
+       popl %esp
+       popal
+       popl %es
+       popl %ds
+       addl $0x8, %esp                 # skip IRQ number and err (which is 0)
+       iret