x86: IDT vector realignment (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 12 Mar 2014 21:49:05 +0000 (14:49 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 29 Mar 2014 01:16:11 +0000 (18:16 -0700)
Lays out what each IDT vector is used for, somewhat merging with the
Plan 9 stuff.  These are the vectors that the processor/LAPIC sees, not
the external IRQs.

This also changes the trap syscall vector to 0x40 (64), and the LAPIC
timer vector.

You need to reinstall your kernel headers and rebuild anything that made
trap based syscalls (parlib and all MCPs).  Not sure if you need to
rebuild the toolchain (probably not).

kern/arch/x86/apic.c
kern/arch/x86/apic9.c
kern/arch/x86/io.h
kern/arch/x86/ioapic.c
kern/arch/x86/ros/syscall.h
kern/arch/x86/ros/syscall32.h
kern/arch/x86/ros/syscall64.h
kern/arch/x86/time.c
kern/arch/x86/trap.c
kern/arch/x86/trap.h
kern/src/alarm.c

index 3a9908a..c997431 100644 (file)
@@ -13,6 +13,7 @@
 #include <arch/x86.h>
 #include <arch/arch.h>
 #include <arch/apic.h>
+#include <trap.h>
 #include <time.h>
 #include <assert.h>
 #include <stdio.h>
@@ -122,7 +123,7 @@ void lapic_set_timer(uint32_t usec, bool periodic)
                            / 1000000;
        uint32_t ticks32 = ((ticks64 >> 32) ? 0xffffffff : ticks64);
        assert(ticks32 > 0);
-       __lapic_set_timer(ticks32, LAPIC_TIMER_DEFAULT_VECTOR, periodic,
+       __lapic_set_timer(ticks32, IdtLAPIC_TIMER, periodic,
                          LAPIC_TIMER_DIVISOR_BITS);
 }
 
index b9f134d..70e1a4e 100644 (file)
@@ -12,6 +12,7 @@
 #include <smp.h>
 #include <ip.h>
 #include <arch/io.h>
+#include <trap.h>
 
 enum {                                                 /* Local APIC registers */
        Id = 0x0020,                            /* Identification */
@@ -287,7 +288,7 @@ int apiconline(void)
         * bits 3-0 0x0f unless the Extended Spurious Vector Enable bit
         * is set in the HyperTransport Transaction Control register.
         */
-       apicrput(Siv, Swen | IdtSPURIOUS);
+       apicrput(Siv, Swen | IdtLAPIC_SPURIOUS);
 
        /*
         * Acknowledge any outstanding interrupts.
@@ -339,12 +340,12 @@ int apiconline(void)
                 /*FALLTHROUGH*/ default:
                        break;
        }
-       apicrput(Lint1, apic->lvt[1] | Im | IdtLINT1);
-       apicrput(Lint0, apic->lvt[0] | Im | IdtLINT0);
+       apicrput(Lint1, apic->lvt[1] | Im | IdtLAPIC_LINT1);
+       apicrput(Lint0, apic->lvt[0] | Im | IdtLAPIC_LINT0);
 
        apicrput(Es, 0);
        apicrget(Es);
-       apicrput(Elvt, IdtERROR);
+       apicrput(Elvt, IdtLAPIC_ERROR);
 
        /*
         * Issue an INIT Level De-Assert to synchronise arbitration ID's.
index 086d2fd..abe27b0 100644 (file)
@@ -7,65 +7,6 @@
  * in the LICENSE file.
  */
 
-enum {
-       VectorNMI = 2,                          /* non-maskable interrupt */
-       VectorBPT = 3,  /* breakpoint */
-       VectorUD = 6,   /* invalid opcode exception */
-       VectorCNA = 7,  /* coprocessor not available */
-       Vector2F = 8,   /* double fault */
-       VectorCSO = 9,  /* coprocessor segment overrun */
-       VectorPF = 14,  /* page fault */
-       Vector15 = 15,  /* reserved */
-       VectorCERR = 16,        /* coprocessor error */
-
-       VectorPIC = 32, /* external i8259 interrupts */
-       IrqCLOCK = 0,
-       IrqKBD = 1,
-       IrqUART1 = 3,
-       IrqUART0 = 4,
-       IrqPCMCIA = 5,
-       IrqFLOPPY = 6,
-       IrqLPT = 7,
-       IrqIRQ7 = 7,
-       IrqAUX = 12,    /* PS/2 port */
-       IrqIRQ13 = 13,  /* coprocessor on 386 */
-       IrqATA0 = 14,
-       IrqATA1 = 15,
-       MaxIrqPIC = 15,
-
-       VectorLAPIC = VectorPIC + 16,   /* local APIC interrupts */
-       IrqLINT0 = VectorLAPIC + 0,
-       IrqLINT1 = VectorLAPIC + 1,
-       IrqTIMER = VectorLAPIC + 2,
-       IrqERROR = VectorLAPIC + 3,
-       IrqPCINT = VectorLAPIC + 4,
-       IrqSPURIOUS = VectorLAPIC + 15,
-       MaxIrqLAPIC = VectorLAPIC + 15,
-
-       VectorSYSCALL = 64,
-
-       VectorAPIC = 65,        /* external APIC interrupts */
-       MaxVectorAPIC = 255,
-};
-
-enum {
-       IdtPIC = 32,                            /* external i8259 interrupts */
-
-       IdtLINT0 = 48,  /* local APIC interrupts */
-       IdtLINT1 = 49,
-       IdtTIMER = 50,
-       IdtERROR = 51,
-       IdtPCINT = 52,
-
-       IdtIPI = 62,
-       IdtSPURIOUS = 63,
-
-       IdtSYSCALL = 64,
-
-       IdtIOAPIC = 65, /* external APIC interrupts */
-
-       IdtMAX = 255,
-};
 
 struct Vkey {
        int tbdf;                                       /* pci: ioapic or msi sources */
index 77a0d8e..62eb75b 100644 (file)
@@ -22,6 +22,7 @@
 #include <ip.h>
 #include <arch/io.h>
 #include <acpi.h>
+#include <trap.h>
 
 struct Rbus {
        struct Rbus *next;
@@ -433,8 +434,8 @@ int ioapicintrenable(Vctl * v)
  */
        if (v->tbdf == BUSUNKNOWN) {
                printk("%s; BUSUNKNOWN\n", __func__);
-               if (v->irq >= IrqLINT0 && v->irq <= MaxIrqLAPIC) {
-                       if (v->irq != IrqSPURIOUS)
+               if (idt_vec_is_lapic(v->irq)) {
+                       if (v->irq != IdtLAPIC_SPURIOUS)
                                v->isr = apiceoi;
                        v->type = "lapic";
                        return v->irq;
@@ -583,7 +584,7 @@ int ioapicintrdisable(int vecno)
         *
         * What about any pending interrupts?
         */
-       if (vecno < 0 || vecno > MaxVectorAPIC) {
+       if (vecno < 0 || vecno > MaxIdtIOAPIC) {
                panic("ioapicintrdisable: vecno %d out of range", vecno);
                return -1;
        }
index cf18be0..a22aa14 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef ROS_INC_ARCH_SYSCALL_H
 #define ROS_INC_ARCH_SYSCALL_H
 
-#define T_SYSCALL      0x80
+#define T_SYSCALL      64
 
 #ifndef ROS_KERNEL
 
index de3db97..b97627a 100644 (file)
@@ -5,8 +5,6 @@
 #error "Do not include include ros/arch/syscall32.h directly"
 #endif
 
-#define T_SYSCALL      0x80
-
 #ifndef ROS_KERNEL
 
 #include <sys/types.h>
index cb4ef1d..4ec8e85 100644 (file)
@@ -5,8 +5,6 @@
 #error "Do not include include ros/arch/syscall64.h directly"
 #endif
 
-#define T_SYSCALL      0x80
-
 #ifndef ROS_KERNEL
 
 #include <sys/types.h>
index 9762787..e363ae9 100644 (file)
@@ -9,6 +9,7 @@
 #include <arch/pic.h>
 #include <arch/apic.h>
 #include <time.h>
+#include <trap.h>
 #include <assert.h>
 #include <stdio.h>
 
@@ -27,7 +28,7 @@ void timer_init(void){
        tscval[1] = read_tsc();
        system_timing.tsc_freq = SINIT(tscval[1] - tscval[0]);
        cprintf("TSC Frequency: %llu\n", system_timing.tsc_freq);
-       __lapic_set_timer(0xffffffff, LAPIC_TIMER_DEFAULT_VECTOR, FALSE,
+       __lapic_set_timer(0xffffffff, IdtLAPIC_TIMER, FALSE,
                          LAPIC_TIMER_DIVISOR_BITS);
        // Mask the LAPIC Timer, so we never receive this interrupt (minor race)
        mask_lapic_lvt(LAPIC_LVT_TIMER);
index 2221491..6bc1079 100644 (file)
@@ -119,6 +119,7 @@ void idt_init(void)
        extern struct trapinfo trap_tbl_end[];
        int i, trap_tbl_size = trap_tbl_end - trap_tbl;
        extern void ISR_default(void);
+       extern void ISR_syscall(void);
 
        /* set all to default, to catch everything */
        for (i = 0; i < 256; i++)
@@ -130,7 +131,11 @@ void idt_init(void)
         * the idt[] */
        for (i = 0; i < trap_tbl_size - 1; i++)
                SETGATE(idt[trap_tbl[i].trapnumber], 0, GD_KT, trap_tbl[i].trapaddr, 0);
-
+       /* Sanity check */
+       assert((uintptr_t)ISR_syscall ==
+              ((uintptr_t)idt[T_SYSCALL].gd_off_63_32 << 32 |
+               (uintptr_t)idt[T_SYSCALL].gd_off_31_16 << 16 |
+               (uintptr_t)idt[T_SYSCALL].gd_off_15_0));
        /* turn on trap-based syscall handling and other user-accessible ints
         * DPL 3 means this can be triggered by the int instruction */
        idt[T_SYSCALL].gd_dpl = SINIT(3);
@@ -183,7 +188,7 @@ void idt_init(void)
 #endif
 
        /* register the generic timer_interrupt() handler for the per-core timers */
-       register_raw_irq(LAPIC_TIMER_DEFAULT_VECTOR, timer_interrupt, NULL);
+       register_raw_irq(IdtLAPIC_TIMER, timer_interrupt, NULL);
        /* register the kernel message handler */
        register_raw_irq(I_KERNEL_MSG, handle_kmsg_ipi, NULL);
 }
@@ -466,7 +471,7 @@ void handle_irq(struct hw_trapframe *hw_tf)
        /* Coupled with cpu_halt() and smp_idle() */
        abort_halt(hw_tf);
        //if (core_id())
-       if (hw_tf->tf_trapno != LAPIC_TIMER_DEFAULT_VECTOR)     /* timer irq */
+       if (hw_tf->tf_trapno != IdtLAPIC_TIMER) /* timer irq */
        if (hw_tf->tf_trapno != 255) /* kmsg */
        if (hw_tf->tf_trapno != 36)     /* serial */
                printd("Incoming IRQ, ISR: %d on core %d\n", hw_tf->tf_trapno,
@@ -561,8 +566,8 @@ int x =     intrenable(irq, handler, irq_arg, tbdf);
        if (x > 0)
                register_raw_irq(x, handler, irq_arg);
 #else
-       register_raw_irq(KERNEL_IRQ_OFFSET + irq, handler, irq_arg);
-       pic_unmask_irq(irq + PIC1_OFFSET);
+       register_raw_irq(irq + IdtPIC, handler, irq_arg);
+       pic_unmask_irq(irq + IdtPIC);
 #endif
        return 0;
 }
index 1a925e5..caeb26e 100644 (file)
@@ -4,10 +4,8 @@
 #include "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)
+
+/* 48-63 are LAPIC vectors */
+#define IdtLAPIC                               (IdtPIC + 16)
+#define IdtLAPIC_LINT0                 (IdtLAPIC + 0)
+#define IdtLAPIC_LINT1                 (IdtLAPIC + 1)
+#define IdtLAPIC_TIMER                 (IdtLAPIC + 2)
+#define IdtLAPIC_ERROR                 (IdtLAPIC + 3)
+#define IdtLAPIC_PCINT                 (IdtLAPIC + 4)
+/* 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.  Plan 9 used 63 (0x3f), but
+ * 55 should have worked too (0x37). */
+#define IdtLAPIC_SPURIOUS              (IdtLAPIC + 15) /* Aka 63, 0x3f */
+#define MaxIdtLAPIC                            (IdtLAPIC + 15)
+
+/* T_SYSCALL is defined by the following include (64) */
 #include <ros/arch/syscall.h>
 
+/* 65-229 are IOAPIC routing vectors (from IOAPIC to LAPIC) */
+#define IdtIOAPIC                              (T_SYSCALL + 1)
+#define MaxIdtIOAPIC                   229
+/* 230-255 are OS IPI vectors */
+#define IdtMAX                                 255
+
+
 #define T_DEFAULT   0x0000beef         // catchall
 
 /* Floating point constants */
@@ -109,6 +141,16 @@ struct irq_handler {
        char name[IRQ_NAME_LEN];
 };
 
+static bool idt_vec_is_pic(int vec)
+{
+       return (IdtPIC <= vec) && (vec <= MaxIdtPIC);
+}
+
+static bool idt_vec_is_lapic(int vec)
+{
+       return (IdtLAPIC <= vec) && (vec <= MaxIdtLAPIC);
+}
+
 /* The kernel's interrupt descriptor table */
 extern gatedesc_t idt[];
 extern pseudodesc_t idt_pd;
index 0b481ef..3e89699 100644 (file)
@@ -322,7 +322,7 @@ void set_pcpu_alarm_interrupt(uint64_t time, struct timer_chain *tchain)
                /* TODO: using the LAPIC vector is a bit ghetto, since that's x86.  But
                 * RISCV ignores the vector field, and we don't have a global IRQ vector
                 * namespace or anything. */
-               send_ipi(rem_pcpui - &per_cpu_info[0], LAPIC_TIMER_DEFAULT_VECTOR);
+               send_ipi(rem_pcpui - &per_cpu_info[0], IdtLAPIC_TIMER);
                return;
        }
        if (time) {