Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


(no commit message)
[palacios.git] / palacios / src / geekos / tss.c
1 /*
2  * x86 TSS data structure and routines
3  * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4  * $Revision: 1.1.1.1 $
5  * 
6  * This is free software.  You are permitted to use,
7  * redistribute, and modify it as specified in the file "COPYING".
8  */
9
10 /*
11  * Source: _Protected Mode Software Architecture_ by Tom Shanley,
12  * ISBN 020155447X.
13  */
14
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>
21
22 #include <geekos/serial.h>
23
24 /*
25  * We use one TSS in GeekOS.
26  */
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;
31
32 static void __inline__ Load_Task_Register(void)
33 {
34     /* Critical: TSS must be marked as not busy */
35     s_tssDesc->type = 0x09;
36
37     /* Load the task register */
38     __asm__ __volatile__ (
39         "ltr %0"
40         :
41         : "a" (s_tssSelector)
42     );
43 }
44
45 /*
46  * Initialize the kernel TSS.  This must be done after the memory and
47  * GDT initialization, but before the scheduler is started.
48  */
49 void Init_TSS(void)
50 {
51   PrintBoth("Initializing TSS\n");
52
53     s_tssDesc = Allocate_Segment_Descriptor();
54     KASSERT(s_tssDesc != 0);
55
56     memset(s_theTSS, '\0', sizeof(struct TSS));
57     Init_TSS_Descriptor(s_tssDesc, s_theTSS);
58
59     s_tssSelector = Selector(0, true, Get_Descriptor_Index(s_tssDesc));
60
61     Load_Task_Register();
62 }
63
64 /*
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.
69  */
70 void Set_Kernel_Stack_Pointer(ulong_t esp0)
71 {
72     s_theTSS->ss0 = KERNEL_DS;
73     s_theTSS->esp0 = esp0;
74
75     /*
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.
80      */
81     Load_Task_Register();
82 }