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;
28 static struct TSS *s_theTSS = (struct TSS *) TSS_LOCATION;
29 static struct Segment_Descriptor *s_tssDesc;
30 static ushort_t s_tssSelector;
32 static void __inline__ Load_Task_Register(void)
34 /* Critical: TSS must be marked as not busy */
35 s_tssDesc->type = 0x09;
37 /* Load the task register */
38 __asm__ __volatile__ (
46 * Initialize the kernel TSS. This must be done after the memory and
47 * GDT initialization, but before the scheduler is started.
51 PrintBoth("Initializing TSS\n");
53 s_tssDesc = Allocate_Segment_Descriptor();
54 KASSERT(s_tssDesc != 0);
56 memset(s_theTSS, '\0', sizeof(struct TSS));
57 Init_TSS_Descriptor(s_tssDesc, s_theTSS);
59 s_tssSelector = Selector(0, true, Get_Descriptor_Index(s_tssDesc));
65 * Set kernel stack pointer.
66 * This should be called before switching to a new
67 * user process, so that interrupts occurring while executing
68 * in user mode will be delivered on the correct stack.
70 void Set_Kernel_Stack_Pointer(ulong_t esp0)
72 s_theTSS->ss0 = KERNEL_DS;
73 s_theTSS->esp0 = esp0;
76 * NOTE: I read on alt.os.development that it is necessary to
77 * reload the task register after modifying a TSS.
78 * I haven't verified this in the IA32 documentation,
79 * but there is certainly no harm in being paranoid.