c291ad6dbe98d9a38cb7dcd23f90ddd5e0ef94a8
[akaros.git] / kern / arch / x86 / trap.h
1 #ifndef ROS_KERN_ARCH_TRAP_H
2 #define ROS_KERN_ARCH_TRAP_H
3
4 #include "msr-index.h"
5
6 #define NUM_IRQS                                        256
7 #define KERNEL_IRQ_OFFSET                       32
8
9 // Trap numbers
10 // These are processor defined:
11 #define T_DIVIDE     0          // divide error
12 #define T_DEBUG      1          // debug exception
13 #define T_NMI        2          // non-maskable interrupt
14 #define T_BRKPT      3          // breakpoint
15 #define T_OFLOW      4          // overflow
16 #define T_BOUND      5          // bounds check
17 #define T_ILLOP      6          // illegal opcode
18 #define T_DEVICE     7          // device not available 
19 #define T_DBLFLT     8          // double fault
20 /* #define T_COPROC  9 */       // reserved (not generated by recent processors)
21 #define T_TSS       10          // invalid task switch segment
22 #define T_SEGNP     11          // segment not present
23 #define T_STACK     12          // stack exception
24 #define T_GPFLT     13          // genernal protection fault
25 #define T_PGFLT     14          // page fault
26 /* #define T_RES    15 */       // reserved
27 #define T_FPERR     16          // floating point error
28 #define T_ALIGN     17          // aligment check
29 #define T_MCHK      18          // machine check
30 #define T_SIMDERR   19          // SIMD floating point error
31
32 // These are arbitrarily chosen, but with care not to overlap
33 // processor defined exceptions or interrupt vectors.
34
35 // T_SYSCALL is defined by the following include:
36 #include <ros/arch/syscall.h>
37
38 #define T_DEFAULT   0x0000beef          // catchall
39
40 /* Floating point constants */
41 #define FP_EXCP_IE                              (1 << 0)        /* invalid op */
42 #define FP_EXCP_DE                              (1 << 1)        /* denormalized op */
43 #define FP_EXCP_ZE                              (1 << 2)        /* div by zero */
44 #define FP_EXCP_OE                              (1 << 3)        /* numeric overflow */
45 #define FP_EXCP_UE                              (1 << 4)        /* numeric underflow */
46 #define FP_EXCP_PE                              (1 << 5)        /* precision */
47
48 #define FP_SW_SF                                (1 << 6)        /* stack fault */
49 #define FP_SW_ES                                (1 << 7)        /* error summary status */
50 #define FP_SW_C0                                (1 << 8)        /* condition codes */
51 #define FP_SW_C1                                (1 << 9)
52 #define FP_SW_C2                                (1 << 10)
53 #define FP_SW_C3                                (1 << 14)
54 #define FP_CW_TOP_SHIFT                 (11)
55 #define FP_CW_TOP_MASK                  (7 << FP_CW_TOP_SHIFT)
56
57 #define FP_CW_PC_SHIFT                  (8)
58 #define FP_CW_PC_MASK                   (3 << FP_CW_PC_SHIFT)
59 #define FP_CW_RC_SHIFT                  (10)
60 #define FP_CW_RC_MASK                   (3 << FP_CW_RC_SHIFT)
61 #define FP_CW_IC                                (1 << 12)
62
63 /* IPIs */
64 /* Testing IPI (used in testing.c) */
65 #define I_TESTING               230
66 /* smp_call_function IPIs, keep in sync with NUM_HANDLER_WRAPPERS (and < 16)
67  * it's important that this begins with 0xf0.  check i386/trap.c for details. */
68 #define I_SMP_CALL0     0xf0 // 240
69 #define I_SMP_CALL1     0xf1
70 #define I_SMP_CALL2     0xf2
71 #define I_SMP_CALL3     0xf3
72 #define I_SMP_CALL4     0xf4
73 #define I_SMP_CALL_LAST I_SMP_CALL4
74 /* Direct/Hardwired IPIs.  Hardwired in trapentry.S */
75 #define I_KERNEL_MSG    255
76
77 #ifndef __ASSEMBLER__
78
79 #ifndef ROS_KERN_TRAP_H
80 #error "Do not include include arch/trap.h directly"
81 #endif
82
83 #include <ros/common.h>
84 #include <arch/mmu.h>
85 #include <ros/trapframe.h>
86 #include <arch/pci.h>
87 #include <arch/coreid.h>
88
89 struct irq_handler {
90         struct irq_handler *next;
91         void (*isr)(struct hw_trapframe *hw_tf, void *data);
92         void *data;
93
94         /* all handlers in the chain need to have the same func pointers.  we only
95          * really use the first one, and the latter are to catch bugs.  also, we
96          * won't be doing a lot of IRQ line sharing */
97         bool (*check_spurious)(int);
98         void (*eoi)(int);
99         void (*mask)(int);
100         void (*unmask)(int);
101
102         int pci_tbdf;
103         int dev_irq;
104         int apic_vector;
105
106         char *type;
107         #define IRQ_NAME_LEN 26
108         char name[IRQ_NAME_LEN];
109 };
110
111 /* The kernel's interrupt descriptor table */
112 extern gatedesc_t idt[];
113 extern pseudodesc_t idt_pd;
114 extern taskstate_t ts;
115 /* Mapping of irq -> PCI device (TODO: make this PCI-agnostic) */
116 extern struct pci_device *irq_pci_map[NUM_IRQS];
117 extern const char *x86_trapname(int trapno);
118 extern void sysenter_handler(void);
119 void backtrace_kframe(struct hw_trapframe *hw_tf);
120
121 /* Defined and set up in in arch/init.c, used for XMM initialization */
122 extern struct ancillary_state x86_default_fpu;
123
124 static inline void save_fp_state(struct ancillary_state *silly)
125 {
126         asm volatile("fxsave %0" : : "m"(*silly));
127 }
128
129 /* TODO: this can trigger a GP fault if MXCSR reserved bits are set.  Callers
130  * will need to handle intercepting the kernel fault. */
131 static inline void restore_fp_state(struct ancillary_state *silly)
132 {
133         asm volatile("fxrstor %0" : : "m"(*silly));
134 }
135
136 /* A regular fninit will only initialize the x87 header part of the FPU, not the
137  * st(n) (MMX) registers, the XMM registers, or the MXCSR state.  So to init,
138  * we'll just keep around a copy of the default FPU state, which we grabbed
139  * during boot, and can copy that over.
140  *
141  * Alternatively, we can fninit, ldmxcsr with the default value, and 0 out all
142  * of the registers manually. */
143 static inline void init_fp_state(void)
144 {
145         restore_fp_state(&x86_default_fpu);
146 }
147
148 static inline void __attribute__((always_inline))
149 set_stack_pointer(uintptr_t sp)
150 {
151         asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp) : "memory", X86_REG_SP);
152 }
153
154 extern segdesc_t *gdt;
155
156 #ifdef CONFIG_X86_64
157 #include <arch/trap64.h>
158 #else
159 #include <arch/trap32.h>
160 #endif
161
162 #endif /* !__ASSEMBLER__ */
163
164 #endif /* !ROS_INC_ARCH_TRAP_H */