Bring in msi support
[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
8 /* 0-31 are hardware traps */
9 #define T_DIVIDE     0          // divide error
10 #define T_DEBUG      1          // debug exception
11 #define T_NMI        2          // non-maskable interrupt
12 #define T_BRKPT      3          // breakpoint
13 #define T_OFLOW      4          // overflow
14 #define T_BOUND      5          // bounds check
15 #define T_ILLOP      6          // illegal opcode
16 #define T_DEVICE     7          // device not available 
17 #define T_DBLFLT     8          // double fault
18 /* #define T_COPROC  9 */       // reserved (not generated by recent processors)
19 #define T_TSS       10          // invalid task switch segment
20 #define T_SEGNP     11          // segment not present
21 #define T_STACK     12          // stack exception
22 #define T_GPFLT     13          // genernal protection fault
23 #define T_PGFLT     14          // page fault
24 /* #define T_RES    15 */       // reserved
25 #define T_FPERR     16          // floating point error
26 #define T_ALIGN     17          // aligment check
27 #define T_MCHK      18          // machine check
28 #define T_SIMDERR   19          // SIMD floating point error
29
30 /* 32-47 are PIC/8259 IRQ vectors */
31 #define IdtPIC                                  32
32 #define IrqCLOCK                                0
33 #define IrqKBD                                  1
34 #define IrqUART1                                3
35 #define IrqUART0                                4
36 #define IrqPCMCIA                               5
37 #define IrqFLOPPY                               6
38 #define IrqLPT                                  7
39 #define IrqAUX                                  12      /* PS/2 port */
40 #define IrqIRQ13                                13      /* coprocessor on 386 */
41 #define IrqATA0                                 14
42 #define IrqATA1                                 15
43 #define MaxIrqPIC                               15
44 #define MaxIdtPIC                               (IdtPIC + MaxIrqPIC)
45
46 /* 48-63 are LAPIC vectors */
47 #define IdtLAPIC                                (IdtPIC + 16)
48 #define IdtLAPIC_TIMER                  (IdtLAPIC + 0)
49 #define IdtLAPIC_THERMAL                (IdtLAPIC + 1)
50 #define IdtLAPIC_PCINT                  (IdtLAPIC + 2)
51 #define IdtLAPIC_LINT0                  (IdtLAPIC + 3)
52 #define IdtLAPIC_LINT1                  (IdtLAPIC + 4)
53 #define IdtLAPIC_ERROR                  (IdtLAPIC + 5)
54 /* Plan 9 apic note: the spurious vector number must have bits 3-0 0x0f
55  * unless the Extended Spurious Vector Enable bit is set in the
56  * HyperTransport Transaction Control register.  Plan 9 used 63 (0x3f). */
57 #define IdtLAPIC_SPURIOUS               (IdtLAPIC + 15) /* Aka 63, 0x3f */
58 #define MaxIdtLAPIC                             (IdtLAPIC + 15)
59
60 /* T_SYSCALL is defined by the following include (64) */
61 #include <ros/arch/syscall.h>
62
63 /* 65-229 are IOAPIC routing vectors (from IOAPIC to LAPIC) */
64 #define IdtIOAPIC                               (T_SYSCALL + 1)
65 #define MaxIdtIOAPIC                    229
66 /* 230-255 are OS IPI vectors */
67 #define IdtMAX                                  255
68
69
70 #define T_DEFAULT   0x0000beef          // catchall
71
72 /* Floating point constants */
73 #define FP_EXCP_IE                              (1 << 0)        /* invalid op */
74 #define FP_EXCP_DE                              (1 << 1)        /* denormalized op */
75 #define FP_EXCP_ZE                              (1 << 2)        /* div by zero */
76 #define FP_EXCP_OE                              (1 << 3)        /* numeric overflow */
77 #define FP_EXCP_UE                              (1 << 4)        /* numeric underflow */
78 #define FP_EXCP_PE                              (1 << 5)        /* precision */
79
80 #define FP_SW_SF                                (1 << 6)        /* stack fault */
81 #define FP_SW_ES                                (1 << 7)        /* error summary status */
82 #define FP_SW_C0                                (1 << 8)        /* condition codes */
83 #define FP_SW_C1                                (1 << 9)
84 #define FP_SW_C2                                (1 << 10)
85 #define FP_SW_C3                                (1 << 14)
86 #define FP_CW_TOP_SHIFT                 (11)
87 #define FP_CW_TOP_MASK                  (7 << FP_CW_TOP_SHIFT)
88
89 #define FP_CW_PC_SHIFT                  (8)
90 #define FP_CW_PC_MASK                   (3 << FP_CW_PC_SHIFT)
91 #define FP_CW_RC_SHIFT                  (10)
92 #define FP_CW_RC_MASK                   (3 << FP_CW_RC_SHIFT)
93 #define FP_CW_IC                                (1 << 12)
94
95 /* IPIs */
96 /* Testing IPI (used in testing.c) */
97 #define I_TESTING               230
98 /* smp_call_function IPIs, keep in sync with NUM_HANDLER_WRAPPERS (and < 16)
99  * it's important that this begins with 0xf0.  check i386/trap.c for details. */
100 #define I_SMP_CALL0     0xf0 // 240
101 #define I_SMP_CALL1     0xf1
102 #define I_SMP_CALL2     0xf2
103 #define I_SMP_CALL3     0xf3
104 #define I_SMP_CALL4     0xf4
105 #define I_SMP_CALL_LAST I_SMP_CALL4
106 /* Direct/Hardwired IPIs.  Hardwired in trapentry.S */
107 #define I_KERNEL_MSG    255
108
109 #ifndef __ASSEMBLER__
110
111 #ifndef ROS_KERN_TRAP_H
112 #error "Do not include include arch/trap.h directly"
113 #endif
114
115 #include <ros/common.h>
116 #include <arch/mmu.h>
117 #include <ros/trapframe.h>
118 #include <arch/pci.h>
119 #include <arch/pic.h>
120 #include <arch/coreid.h>
121 #include <arch/io.h>
122
123 struct vkey {
124         int tbdf;
125         int dev_irq;
126 };
127
128 struct irq_handler {
129         struct irq_handler *next;
130         void (*isr)(struct hw_trapframe *hw_tf, void *data);
131         void *data;
132
133         /* all handlers in the chain need to have the same func pointers.  we only
134          * really use the first one, and the latter are to catch bugs.  also, we
135          * won't be doing a lot of IRQ line sharing */
136         bool (*check_spurious)(int);
137         void (*eoi)(int);
138         void (*mask)(int);
139         void (*unmask)(int);
140         int (*route_irq)(int, int);
141
142         int tbdf;
143         int dev_irq;
144         int apic_vector;
145
146         char *type;
147         #define IRQ_NAME_LEN 26
148         char name[IRQ_NAME_LEN];
149 };
150
151 /* The kernel's interrupt descriptor table */
152 extern gatedesc_t idt[];
153 extern pseudodesc_t idt_pd;
154 extern taskstate_t ts;
155 int bus_irq_setup(struct irq_handler *irq_h);   /* ioapic.c */
156 extern const char *x86_trapname(int trapno);
157 extern void sysenter_handler(void);
158 void backtrace_kframe(struct hw_trapframe *hw_tf);
159
160 /* Defined and set up in in arch/init.c, used for XMM initialization */
161 extern struct ancillary_state x86_default_fpu;
162
163 static inline void save_fp_state(struct ancillary_state *silly)
164 {
165         asm volatile("fxsave %0" : : "m"(*silly));
166 }
167
168 /* TODO: this can trigger a GP fault if MXCSR reserved bits are set.  Callers
169  * will need to handle intercepting the kernel fault. */
170 static inline void restore_fp_state(struct ancillary_state *silly)
171 {
172         asm volatile("fxrstor %0" : : "m"(*silly));
173 }
174
175 /* A regular fninit will only initialize the x87 header part of the FPU, not the
176  * st(n) (MMX) registers, the XMM registers, or the MXCSR state.  So to init,
177  * we'll just keep around a copy of the default FPU state, which we grabbed
178  * during boot, and can copy that over.
179  *
180  * Alternatively, we can fninit, ldmxcsr with the default value, and 0 out all
181  * of the registers manually. */
182 static inline void init_fp_state(void)
183 {
184         restore_fp_state(&x86_default_fpu);
185 }
186
187 static inline void __attribute__((always_inline))
188 set_stack_pointer(uintptr_t sp)
189 {
190         asm volatile("mov %0,%%"X86_REG_SP"" : : "r"(sp) : "memory", X86_REG_SP);
191 }
192
193 extern segdesc_t *gdt;
194
195 #ifdef CONFIG_X86_64
196 #include <arch/trap64.h>
197 #else
198 #include <arch/trap32.h>
199 #endif
200
201 #endif /* !__ASSEMBLER__ */
202
203 #endif /* !ROS_INC_ARCH_TRAP_H */