POK(kernelpart)
gdt.c
Go to the documentation of this file.
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Thu Jan 15 23:34:13 2009
15  */
16 
17 
18 #include <libc.h>
19 
20 #include <types.h>
21 #include <errno.h>
22 
23 #include "gdt.h"
24 #include "sysdesc.h"
25 #include "tss.h"
26 
27 #ifndef POK_NEEDS_THREADS
28 #define POK_CONFIG_NB_THREADS 0
29 #endif
30 
31 #ifndef POK_NEEDS_PARTITIONS
32 #define POK_CONFIG_NB_PARTITIONS 0
33 #endif
34 
35 #define GDT_SIZE 256
36 
37 gdt_entry_t pok_gdt[GDT_SIZE];
38 
39 tss_t pok_tss;
40 
42 {
43  sysdesc_t sysdesc;
44 
45  /* Set null descriptor and clear table */
46  memset(pok_gdt, 0, sizeof (gdt_entry_t) * GDT_SIZE);
47 
48  /* Set kernel descriptors */
51 
52  /* Load GDT */
53  sysdesc.limit = sizeof (pok_gdt);
54  sysdesc.base = (uint32_t)pok_gdt;
55 
56  asm ("lgdt %0"
57  :
58  : "m" (sysdesc));
59 
60  /* Reload Segments */
61  asm ("ljmp %0, $1f \n"
62  "1: \n"
63  "mov %1, %%ax \n"
64  "mov %%ax, %%ds \n"
65  "mov %%ax, %%es \n"
66  "mov %%ax, %%fs \n"
67  "mov %%ax, %%gs \n"
68  "mov %%ax, %%ss \n"
69  :
70  : "i" (GDT_CORE_CODE_SEGMENT << 3),
71  "i" (GDT_CORE_DATA_SEGMENT << 3)
72  : "eax");
73 
74  pok_tss_init();
75 
76  return (POK_ERRNO_OK);
77 }
78 
80 {
82 
83  memset(&pok_tss, 0, sizeof (tss_t));
84 
86 
88  sizeof (tss_t), GDTE_TSS, 0);
89 
90  asm ("ltr %0" : :"m"(sel));
91  return (POK_ERRNO_OK);
92 }
93 
95 {
96  pok_tss.esp0 = esp0;
97 }
98 
100  uint32_t base_address,
101  uint32_t limit,
102  e_gdte_type t,
103  int dpl)
104 {
105  if (limit > (1 << 20)) /* 4K granularity */
106  {
107  pok_gdt[index].limit_low = (limit >> 12) & 0xFFFF;
108  pok_gdt[index].limit_high = (limit >> 28) & 0xF;
109  pok_gdt[index].granularity = 1;
110  }
111  else /* 1B granularity */
112  {
113  pok_gdt[index].limit_low = limit & 0xFFFF;
114  pok_gdt[index].limit_high = (limit >> 16) & 0xFF;
115  pok_gdt[index].granularity = 0;
116  }
117 
118  pok_gdt[index].base_low = base_address & 0xFFFFFF;
119  pok_gdt[index].base_high = (base_address >> 24) & 0xFF;
120 
121  pok_gdt[index].type = t & 0xF;
122  pok_gdt[index].dpl = dpl & 0x3;
123 
124  pok_gdt[index].s = 1; /* Segment is data/code type */
125  pok_gdt[index].present = 1;
126  pok_gdt[index].available = 0;
127  pok_gdt[index].op_size = 1; /* We work on 32 bits segments */
128 }
129 
131  uint32_t base_address,
132  uint32_t limit,
133  e_gdte_type t,
134  int dpl)
135 {
136  pok_gdt[index].limit_low = limit & 0xFFFF;
137  pok_gdt[index].limit_high = (limit >> 16) & 0xFF;
138  pok_gdt[index].base_low = base_address & 0xFFFFFF;
139  pok_gdt[index].base_high = (base_address >> 24) & 0xFF;
140 
141  pok_gdt[index].type = t & 0xF;
142  pok_gdt[index].dpl = dpl & 0x3;
143 
144  pok_gdt[index].s = 0; /* Segment is system type */
145  pok_gdt[index].present = 1;
146  pok_gdt[index].available = 0;
147  pok_gdt[index].op_size = 0;
148 }
149 
150 void gdt_enable(uint16_t index)
151 {
152  pok_gdt[index].present = 1;
153 }
154 
156 {
157  pok_gdt[index].present = 0;
158 }
159 
160 /*
161  * DEPRECATED
162  *
163 uint32_t gdt_segment_base(uint16_t idx)
164 {
165  uint32_t base;
166 
167  base = pok_gdt[idx].base_low | (pok_gdt[idx].base_high << 24);
168 
169  return base;
170 }
171 */
172