diff options
Diffstat (limited to 'i386/i386/ktss.c')
-rw-r--r-- | i386/i386/ktss.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/i386/i386/ktss.c b/i386/i386/ktss.c index 917e6305..34cb6df2 100644 --- a/i386/i386/ktss.c +++ b/i386/i386/ktss.c @@ -35,15 +35,18 @@ #include "seg.h" #include "gdt.h" #include "ktss.h" +#include "mp_desc.h" /* A kernel TSS with a complete I/O bitmap. */ struct task_tss ktss; void -ktss_init(void) +ktss_fill(struct task_tss *myktss, struct real_descriptor *mygdt) { - /* XXX temporary exception stack */ + /* XXX temporary exception stacks */ + /* FIXME: make it per-processor */ static int exception_stack[1024]; + static int double_fault_stack[1024]; #ifdef MACH_RING1 /* Xen won't allow us to do any I/O by default anyway, just register @@ -52,19 +55,38 @@ ktss_init(void) panic("couldn't register exception stack\n"); #else /* MACH_RING1 */ /* Initialize the master TSS descriptor. */ - fill_gdt_sys_descriptor(KERNEL_TSS, - kvtolin(&ktss), sizeof(struct task_tss) - 1, + _fill_gdt_sys_descriptor(mygdt, KERNEL_TSS, + kvtolin(myktss), sizeof(struct task_tss) - 1, ACC_PL_K|ACC_TSS, 0); /* Initialize the master TSS. */ - ktss.tss.ss0 = KERNEL_DS; - ktss.tss.esp0 = (unsigned long)(exception_stack+1024); - ktss.tss.io_bit_map_offset = IOPB_INVAL; +#ifdef __x86_64__ + myktss->tss.rsp0 = (unsigned long)(exception_stack+1024); + myktss->tss.ist1 = (unsigned long)(double_fault_stack+1024); +#else /* ! __x86_64__ */ + myktss->tss.ss0 = KERNEL_DS; + myktss->tss.esp0 = (unsigned long)(exception_stack+1024); +#endif /* __x86_64__ */ + + myktss->tss.io_bit_map_offset = IOPB_INVAL; /* Set the last byte in the I/O bitmap to all 1's. */ - ktss.barrier = 0xff; + myktss->barrier = 0xff; /* Load the TSS. */ ltr(KERNEL_TSS); #endif /* MACH_RING1 */ } +void +ktss_init(void) +{ + ktss_fill(&ktss, gdt); +} + +#if NCPUS > 1 +void +ap_ktss_init(int cpu) +{ + ktss_fill(&mp_desc_table[cpu]->ktss, mp_gdt[cpu]); +} +#endif |