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>
23 #include <geekos/debug.h>
27 * We use one TSS in GeekOS.
29 static struct TSS s_theTSS;
30 static struct Segment_Descriptor *s_tssDesc;
31 static ushort_t s_tssSelector;
33 static void __inline__ Load_Task_Register(void)
36 /* Critical: TSS must be marked as not busy */
37 s_tssDesc->type = 0x09;
39 /* Load the task register */
40 __asm__ __volatile__ (
48 * Initialize the kernel TSS. This must be done after the memory and
49 * GDT initialization, but before the scheduler is started.
53 PrintBoth("Initializing TSS\n");
55 s_tssDesc = Allocate_Segment_Descriptor();
56 KASSERT(s_tssDesc != 0);
58 memset(&s_theTSS, '\0', sizeof(struct TSS));
59 Init_TSS_Descriptor(s_tssDesc, &s_theTSS);
61 s_tssSelector = Selector(0, true, Get_Descriptor_Index(s_tssDesc));
67 * Set kernel stack pointer.
68 * This should be called before switching to a new
69 * user process, so that interrupts occurring while executing
70 * in user mode will be delivered on the correct stack.
72 void Set_Kernel_Stack_Pointer(ulong_t esp0)
74 s_theTSS.ss0 = KERNEL_DS;
78 * NOTE: I read on alt.os.development that it is necessary to
79 * reload the task register after modifying a TSS.
80 * I haven't verified this in the IA32 documentation,
81 * but there is certainly no harm in being paranoid.
87 /* JRL THIS FUCKING SUCKS */
90 return (uint_t)(&s_theTSS);
92 uint_t GetTR_Limit() {
93 return sizeof(struct TSS);
96 ushort_t GetTR_Selector() {