| #ifndef ROS_KERN_ARCH_TRAP_H |
| #define ROS_KERN_ARCH_TRAP_H |
| |
| #include "msr-index.h" |
| |
| #define NUM_IRQS 256 |
| #define KERNEL_IRQ_OFFSET 32 |
| |
| // Trap numbers |
| // These are processor defined: |
| #define T_DIVIDE 0 // divide error |
| #define T_DEBUG 1 // debug exception |
| #define T_NMI 2 // non-maskable interrupt |
| #define T_BRKPT 3 // breakpoint |
| #define T_OFLOW 4 // overflow |
| #define T_BOUND 5 // bounds check |
| #define T_ILLOP 6 // illegal opcode |
| #define T_DEVICE 7 // device not available |
| #define T_DBLFLT 8 // double fault |
| /* #define T_COPROC 9 */ // reserved (not generated by recent processors) |
| #define T_TSS 10 // invalid task switch segment |
| #define T_SEGNP 11 // segment not present |
| #define T_STACK 12 // stack exception |
| #define T_GPFLT 13 // genernal protection fault |
| #define T_PGFLT 14 // page fault |
| /* #define T_RES 15 */ // reserved |
| #define T_FPERR 16 // floating point error |
| #define T_ALIGN 17 // aligment check |
| #define T_MCHK 18 // machine check |
| #define T_SIMDERR 19 // SIMD floating point error |
| |
| // These are arbitrarily chosen, but with care not to overlap |
| // processor defined exceptions or interrupt vectors. |
| |
| // T_SYSCALL is defined by the following include: |
| #include <ros/arch/syscall.h> |
| |
| #define T_DEFAULT 0x0000beef // catchall |
| |
| /* Page faults return the nature of the fault in the bits of the error code: */ |
| #define PF_ERROR_PRESENT 0x01 |
| #define PF_ERROR_WRITE 0x02 |
| #define PF_ERROR_USER 0x04 |
| |
| /* Floating point constants */ |
| #define FP_EXCP_IE (1 << 0) /* invalid op */ |
| #define FP_EXCP_DE (1 << 1) /* denormalized op */ |
| #define FP_EXCP_ZE (1 << 2) /* div by zero */ |
| #define FP_EXCP_OE (1 << 3) /* numeric overflow */ |
| #define FP_EXCP_UE (1 << 4) /* numeric underflow */ |
| #define FP_EXCP_PE (1 << 5) /* precision */ |
| |
| #define FP_SW_SF (1 << 6) /* stack fault */ |
| #define FP_SW_ES (1 << 7) /* error summary status */ |
| #define FP_SW_C0 (1 << 8) /* condition codes */ |
| #define FP_SW_C1 (1 << 9) |
| #define FP_SW_C2 (1 << 10) |
| #define FP_SW_C3 (1 << 14) |
| #define FP_CW_TOP_SHIFT (11) |
| #define FP_CW_TOP_MASK (7 << FP_CW_TOP_SHIFT) |
| |
| #define FP_CW_PC_SHIFT (8) |
| #define FP_CW_PC_MASK (3 << FP_CW_PC_SHIFT) |
| #define FP_CW_RC_SHIFT (10) |
| #define FP_CW_RC_MASK (3 << FP_CW_RC_SHIFT) |
| #define FP_CW_IC (1 << 12) |
| |
| /* IPIs */ |
| /* Testing IPI (used in testing.c) */ |
| #define I_TESTING 230 |
| /* smp_call_function IPIs, keep in sync with NUM_HANDLER_WRAPPERS (and < 16) |
| * it's important that this begins with 0xf0. check i386/trap.c for details. */ |
| #define I_SMP_CALL0 0xf0 // 240 |
| #define I_SMP_CALL1 0xf1 |
| #define I_SMP_CALL2 0xf2 |
| #define I_SMP_CALL3 0xf3 |
| #define I_SMP_CALL4 0xf4 |
| #define I_SMP_CALL_LAST I_SMP_CALL4 |
| /* Direct/Hardwired IPIs. Hardwired in trapentry.S */ |
| #define I_KERNEL_MSG 255 |
| |
| #ifndef __ASSEMBLER__ |
| |
| #ifndef ROS_KERN_TRAP_H |
| #error "Do not include include arch/trap.h directly" |
| #endif |
| |
| #include <ros/common.h> |
| #include <arch/mmu.h> |
| #include <ros/trapframe.h> |
| #include <arch/pci.h> |
| |
| /* The kernel's interrupt descriptor table */ |
| extern gatedesc_t idt[]; |
| extern pseudodesc_t idt_pd; |
| extern taskstate_t ts; |
| /* Mapping of irq -> PCI device (TODO: make this PCI-agnostic) */ |
| extern struct pci_device *irq_pci_map[NUM_IRQS]; |
| extern const char *x86_trapname(int trapno); |
| extern void sysenter_handler(void); |
| void backtrace_kframe(struct hw_trapframe *hw_tf); |
| |
| /* Defined and set up in in arch/init.c, used for XMM initialization */ |
| extern struct ancillary_state x86_default_fpu; |
| |
| static inline void save_fp_state(struct ancillary_state *silly) |
| { |
| asm volatile("fxsave %0" : : "m"(*silly)); |
| } |
| |
| /* TODO: this can trigger a GP fault if MXCSR reserved bits are set. Callers |
| * will need to handle intercepting the kernel fault. */ |
| static inline void restore_fp_state(struct ancillary_state *silly) |
| { |
| asm volatile("fxrstor %0" : : "m"(*silly)); |
| } |
| |
| /* A regular fninit will only initialize the x87 header part of the FPU, not the |
| * st(n) (MMX) registers, the XMM registers, or the MXCSR state. So to init, |
| * we'll just keep around a copy of the default FPU state, which we grabbed |
| * during boot, and can copy that over. |
| * |
| * Alternatively, we can fninit, ldmxcsr with the default value, and 0 out all |
| * of the registers manually. */ |
| static inline void init_fp_state(void) |
| { |
| restore_fp_state(&x86_default_fpu); |
| } |
| |
| static inline void __attribute__((always_inline)) |
| set_stack_pointer(uintptr_t sp) |
| { |
| asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp) : "memory", X86_REG_SP); |
| } |
| |
| extern segdesc_t *gdt; |
| |
| #ifdef CONFIG_X86_64 |
| #include <arch/trap64.h> |
| #else |
| #include <arch/trap32.h> |
| #endif |
| |
| #endif /* !__ASSEMBLER__ */ |
| |
| #endif /* !ROS_INC_ARCH_TRAP_H */ |