Added generic backtrace functions to allow backtrace output on buffers
[akaros.git] / kern / arch / x86 / trap.h
index c3ff7f0..2411ff0 100644 (file)
@@ -1,13 +1,12 @@
-#ifndef ROS_KERN_ARCH_TRAP_H
+#pragma once
+
 #define ROS_KERN_ARCH_TRAP_H
 
-#include "msr-index.h"
+#include <ros/arch/msr-index.h>
 
 #define NUM_IRQS                                       256
-#define KERNEL_IRQ_OFFSET                      32
 
-// Trap numbers
-// These are processor defined:
+/* 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_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:
+/* 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_VMMCP_POSTED                         (I_SMP_CALL_LAST + 1)
+#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_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
 #include <arch/mmu.h>
 #include <ros/trapframe.h>
 #include <arch/pci.h>
+#include <arch/pic.h>
+#include <arch/topology.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;
-/* Mapping of irq -> PCI device (TODO: make this PCI-agnostic) */
-extern struct pci_device *irq_pci_map[NUM_IRQS];
+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);
@@ -128,14 +188,16 @@ 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;
 
-#ifdef CONFIG_X86_64
 #include <arch/trap64.h>
-#else
-#include <arch/trap32.h>
-#endif
 
 #endif /* !__ASSEMBLER__ */
-
-#endif /* !ROS_INC_ARCH_TRAP_H */