|  | #ifndef ROS_KERN_ARCH_TRAP_H | 
|  | #define ROS_KERN_ARCH_TRAP_H | 
|  |  | 
|  | #include "msr-index.h" | 
|  |  | 
|  | #define NUM_IRQS					256 | 
|  |  | 
|  | /* 0-31 are hardware traps */ | 
|  | #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 | 
|  |  | 
|  | /* 32-47 are PIC/8259 IRQ vectors */ | 
|  | #define IdtPIC					32 | 
|  | #define IrqCLOCK				0 | 
|  | #define IrqKBD					1 | 
|  | #define IrqUART1				3 | 
|  | #define IrqUART0				4 | 
|  | #define IrqPCMCIA				5 | 
|  | #define IrqFLOPPY				6 | 
|  | #define IrqLPT					7 | 
|  | #define IrqAUX					12	/* PS/2 port */ | 
|  | #define IrqIRQ13				13	/* coprocessor on 386 */ | 
|  | #define IrqATA0					14 | 
|  | #define IrqATA1					15 | 
|  | #define MaxIrqPIC				15 | 
|  | #define MaxIdtPIC				(IdtPIC + MaxIrqPIC) | 
|  |  | 
|  | /* T_SYSCALL is defined by the following include (48) */ | 
|  | #include <ros/arch/syscall.h> | 
|  |  | 
|  | /* 49-223 are IOAPIC routing vectors (from IOAPIC to LAPIC) */ | 
|  | #define IdtIOAPIC				(T_SYSCALL + 1) | 
|  | #define MaxIdtIOAPIC			223 | 
|  |  | 
|  | /* 224-239 are OS IPI vectors (0xe0-0xef) */ | 
|  | /* smp_call_function IPIs, keep in sync with NUM_HANDLER_WRAPPERS. | 
|  | * SMP_CALL0 needs to be 16-aligned (we mask in x86/trap.c).  If you move these, | 
|  | * also change INIT_HANDLER_WRAPPER */ | 
|  | #define I_SMP_CALL0				224 | 
|  | #define I_SMP_CALL1				(I_SMP_CALL0 + 1) | 
|  | #define I_SMP_CALL2				(I_SMP_CALL0 + 2) | 
|  | #define I_SMP_CALL3				(I_SMP_CALL0 + 3) | 
|  | #define I_SMP_CALL4				(I_SMP_CALL0 + 4) | 
|  | #define I_SMP_CALL_LAST			I_SMP_CALL4 | 
|  | #define I_TESTING				237 	/* Testing IPI (used in testing.c) */ | 
|  | #define I_POKE_CORE				238 | 
|  | #define I_KERNEL_MSG			239 | 
|  |  | 
|  | /* 240-255 are LAPIC vectors (0xf0-0xff), hightest priority class */ | 
|  | #define IdtLAPIC				240 | 
|  | #define IdtLAPIC_TIMER			(IdtLAPIC + 0) | 
|  | #define IdtLAPIC_THERMAL		(IdtLAPIC + 1) | 
|  | #define IdtLAPIC_PCINT			(IdtLAPIC + 2) | 
|  | #define IdtLAPIC_LINT0			(IdtLAPIC + 3) | 
|  | #define IdtLAPIC_LINT1			(IdtLAPIC + 4) | 
|  | #define IdtLAPIC_ERROR			(IdtLAPIC + 5) | 
|  | /* Plan 9 apic note: the spurious vector number must have bits 3-0 0x0f | 
|  | * unless the Extended Spurious Vector Enable bit is set in the | 
|  | * HyperTransport Transaction Control register.  On some intel machines, those | 
|  | * bits are hardwired to 1s (SDM 3-10.9). */ | 
|  | #define IdtLAPIC_SPURIOUS		(IdtLAPIC + 0xf) /* Aka 255, 0xff */ | 
|  | #define MaxIdtLAPIC				(IdtLAPIC + 0xf) | 
|  |  | 
|  | #define IdtMAX					255 | 
|  |  | 
|  | #define T_DEFAULT   0x0000beef		// catchall | 
|  |  | 
|  | /* 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) | 
|  |  | 
|  | #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> | 
|  | #include <arch/pic.h> | 
|  | #include <arch/coreid.h> | 
|  | #include <arch/io.h> | 
|  |  | 
|  | struct irq_handler { | 
|  | struct irq_handler *next; | 
|  | void (*isr)(struct hw_trapframe *hw_tf, void *data); | 
|  | void *data; | 
|  | int apic_vector; | 
|  |  | 
|  | /* all handlers in the chain need to have the same func pointers.  we only | 
|  | * really use the first one, and the latter are to catch bugs.  also, we | 
|  | * won't be doing a lot of IRQ line sharing */ | 
|  | bool (*check_spurious)(int); | 
|  | void (*eoi)(int); | 
|  | void (*mask)(struct irq_handler *irq_h, int vec); | 
|  | void (*unmask)(struct irq_handler *irq_h, int vec); | 
|  | void (*route_irq)(struct irq_handler *irq_h, int vec, int dest); | 
|  |  | 
|  | int tbdf; | 
|  | int dev_irq; | 
|  |  | 
|  | void *dev_private; | 
|  | char *type; | 
|  | #define IRQ_NAME_LEN 26 | 
|  | char name[IRQ_NAME_LEN]; | 
|  | }; | 
|  |  | 
|  | /* The kernel's interrupt descriptor table */ | 
|  | extern gatedesc_t idt[]; | 
|  | extern pseudodesc_t idt_pd; | 
|  | extern taskstate_t ts; | 
|  | int bus_irq_setup(struct irq_handler *irq_h);	/* ioapic.c */ | 
|  | 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); | 
|  | } | 
|  |  | 
|  | static inline void __attribute__((always_inline)) | 
|  | set_frame_pointer(uintptr_t fp) | 
|  | { | 
|  | /* note we can't list BP as a clobber - the compiler will flip out.  makes | 
|  | * me wonder if clobbering SP above makes a difference (probably not) */ | 
|  | asm volatile("mov %0,%%"X86_REG_BP"" : : "r"(fp) : "memory"); | 
|  | } | 
|  |  | 
|  | extern segdesc_t *gdt; | 
|  |  | 
|  | #include <arch/trap64.h> | 
|  |  | 
|  | #endif /* !__ASSEMBLER__ */ | 
|  |  | 
|  | #endif /* !ROS_INC_ARCH_TRAP_H */ |