X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=test%2Fgeekos_test_vm%2Fsrc%2Fgeekos%2Ftss.c;fp=test%2Fgeekos_test_vm%2Fsrc%2Fgeekos%2Ftss.c;h=2cdb9682e16b1319b41d7d845212ca3eda96af4c;hp=0000000000000000000000000000000000000000;hb=a70930549d1b741704dd7af4e6bb0e89f6f8a519;hpb=afb634a80f946634454a5d067a92aa600227bd93 diff --git a/test/geekos_test_vm/src/geekos/tss.c b/test/geekos_test_vm/src/geekos/tss.c new file mode 100644 index 0000000..2cdb968 --- /dev/null +++ b/test/geekos_test_vm/src/geekos/tss.c @@ -0,0 +1,85 @@ +/* + * x86 TSS data structure and routines + * Copyright (c) 2001,2004 David H. Hovemeyer + * $Revision: 1.1 $ + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "COPYING". + */ + +/* + * Source: _Protected Mode Software Architecture_ by Tom Shanley, + * ISBN 020155447X. + */ + +#include +#include +#include +#include +#include +#include + +#include + +/* + * We use one TSS in GeekOS. + */ +static struct TSS s_theTSS; + +// JRL: why??? Should just call Alloc_Page(), otherwise we have dependencies all over the place +//static struct TSS *s_theTSS = (struct TSS *) TSS_LOCATION; + +static struct Segment_Descriptor *s_tssDesc; +static ushort_t s_tssSelector; + +static void __inline__ Load_Task_Register(void) +{ + /* Critical: TSS must be marked as not busy */ + s_tssDesc->type = 0x09; + + /* Load the task register */ + __asm__ __volatile__ ( + "ltr %0" + : + : "a" (s_tssSelector) + ); +} + +/* + * Initialize the kernel TSS. This must be done after the memory and + * GDT initialization, but before the scheduler is started. + */ +void Init_TSS(void) +{ + PrintBoth("Initializing TSS\n"); + + s_tssDesc = Allocate_Segment_Descriptor(); + KASSERT(s_tssDesc != 0); + + memset(&s_theTSS, '\0', sizeof(struct TSS)); + Init_TSS_Descriptor(s_tssDesc, &s_theTSS); + + s_tssSelector = Selector(0, true, Get_Descriptor_Index(s_tssDesc)); + + Load_Task_Register(); +} + +/* + * Set kernel stack pointer. + * This should be called before switching to a new + * user process, so that interrupts occurring while executing + * in user mode will be delivered on the correct stack. + */ +void Set_Kernel_Stack_Pointer(ulong_t esp0) +{ + s_theTSS.ss0 = KERNEL_DS; + s_theTSS.esp0 = esp0; + + /* + * NOTE: I read on alt.os.development that it is necessary to + * reload the task register after modifying a TSS. + * I haven't verified this in the IA32 documentation, + * but there is certainly no harm in being paranoid. + */ + Load_Task_Register(); +}