2 * x86 TSS data structure and routines
3 * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
6 * This is free software. You are permitted to use,
7 * redistribute, and modify it as specified in the file "COPYING".
11 * Source: _Protected Mode Software Architecture_ by Tom Shanley,
15 #include <geekos/kassert.h>
16 #include <geekos/defs.h>
17 #include <geekos/gdt.h>
18 #include <geekos/segment.h>
19 #include <geekos/string.h>
20 #include <geekos/tss.h>
22 #include <geekos/serial.h>
25 * We use one TSS in GeekOS.
27 static struct TSS s_theTSS;
29 // JRL: why??? Should just call Alloc_Page(), otherwise we have dependencies all over the place
30 //static struct TSS *s_theTSS = (struct TSS *) TSS_LOCATION;
32 static struct Segment_Descriptor *s_tssDesc;
33 static ushort_t s_tssSelector;
35 static void __inline__ Load_Task_Register(void)
37 /* Critical: TSS must be marked as not busy */
38 s_tssDesc->type = 0x09;
40 /* Load the task register */
41 __asm__ __volatile__ (
49 * Initialize the kernel TSS. This must be done after the memory and
50 * GDT initialization, but before the scheduler is started.
54 PrintBoth("Initializing TSS\n");
56 s_tssDesc = Allocate_Segment_Descriptor();
57 KASSERT(s_tssDesc != 0);
59 memset(&s_theTSS, '\0', sizeof(struct TSS));
60 Init_TSS_Descriptor(s_tssDesc, &s_theTSS);
62 s_tssSelector = Selector(0, true, Get_Descriptor_Index(s_tssDesc));
68 * Set kernel stack pointer.
69 * This should be called before switching to a new
70 * user process, so that interrupts occurring while executing
71 * in user mode will be delivered on the correct stack.
73 void Set_Kernel_Stack_Pointer(ulong_t esp0)
75 s_theTSS.ss0 = KERNEL_DS;
79 * NOTE: I read on alt.os.development that it is necessary to
80 * reload the task register after modifying a TSS.
81 * I haven't verified this in the IA32 documentation,
82 * but there is certainly no harm in being paranoid.