17 |
|
|
18 |
#include <rtmk/i386/vm-param.h> |
#include <rtmk/i386/vm-param.h> |
19 |
|
|
20 |
|
#include "tm.h" |
21 |
#include "cpus.h" |
#include "cpus.h" |
22 |
#include "i386-segment.h" |
#include "i386-segment.h" |
23 |
#include "libkern.h" |
#include "libkern.h" |
33 |
_DESC_STATIC struct segment_descriptor ldt [SZLDT]; |
_DESC_STATIC struct segment_descriptor ldt [SZLDT]; |
34 |
_DESC_STATIC struct segment_descriptor idt [SZIDT]; |
_DESC_STATIC struct segment_descriptor idt [SZIDT]; |
35 |
|
|
36 |
struct tss_segment ktss; |
struct tss_segment ktss [NCPUS]; |
37 |
|
|
38 |
/* Fill descriptor DESC with BASe, LIMIT, ACCESS and SZ. |
/* Fill descriptor DESC with BASe, LIMIT, ACCESS and SZ. |
39 |
Adjust size if limit is above (or equal to) one megabyte. */ |
Adjust size if limit is above (or equal to) one megabyte. */ |
126 |
|
|
127 |
/* Global descriptor table - in pseudo format. */ |
/* Global descriptor table - in pseudo format. */ |
128 |
|
|
129 |
static struct segment_pseudo gdttable [] = |
static struct segment_pseudo gdttable [7 + NCPUS] = |
130 |
{ |
{ |
131 |
/*x08*/ { 1, VM_KERN_MIN_ADDRESS, |
/*x08*/ { 1, VM_KERN_MIN_ADDRESS, |
132 |
/*(VM_KERN_MAX_ADDRESS - VM_KERN_MIN_ADDRESS - 1)*/ 0xffffffff >> 12, |
/*(VM_KERN_MAX_ADDRESS - VM_KERN_MIN_ADDRESS - 1)*/ 0xffffffff >> 12, |
144 |
(VM_USER_MAX_ADDRESS - VM_USER_MIN_ADDRESS - 1) >> 12, |
(VM_USER_MAX_ADDRESS - VM_USER_MIN_ADDRESS - 1) >> 12, |
145 |
SZ_32 | SZ_G, |
SZ_32 | SZ_G, |
146 |
ACC_PL_U | ACC_DATA_W }, |
ACC_PL_U | ACC_DATA_W }, |
147 |
/*x28*/ { 5, (int) & ktss, /* tss */ |
/*x28*/ { 5, (int) ldt, /* ldt */ |
|
sizeof ktss - 1, |
|
|
0, |
|
|
ACC_PL_K | ACC_TSS }, |
|
|
/*x30*/ { 6, 0x00000000, /* user tss */ |
|
|
0, |
|
|
0, |
|
|
ACC_PL_U | ACC_TSS }, |
|
|
/*x38*/ { 7, (int) ldt, /* ldt */ |
|
148 |
(SZLDT * 8) - 1, |
(SZLDT * 8) - 1, |
149 |
0, |
0, |
150 |
ACC_PL_K | ACC_LDT }, |
ACC_PL_K | ACC_LDT }, |
151 |
/*x40*/ { 8, 0x00000000, /* user ldt */ |
/*x30*/ { 6, 0x00000000, /* user ldt */ |
152 |
0, |
0, |
153 |
0, |
0, |
154 |
ACC_PL_U | ACC_LDT }, |
ACC_PL_U | ACC_LDT }, |
199 |
/* Clear fs/gs... */ |
/* Clear fs/gs... */ |
200 |
set_fs (0); |
set_fs (0); |
201 |
set_gs (0); |
set_gs (0); |
|
|
|
|
/* Set kernel TSS. */ |
|
|
__asm__ __volatile__ ("ltr %0" :: "rm" ((unsigned short) KERNEL_TSS)); |
|
202 |
} |
} |
203 |
|
|
204 |
/* Initialize (load) LDT. We just load ldt register with KERNEL_LDT. */ |
/* Initialize (load) LDT. We just load ldt register with KERNEL_LDT. */ |
226 |
segments_init (void) |
segments_init (void) |
227 |
{ |
{ |
228 |
extern struct callgate_pseudo idttable[]; /* From locore.S. */ |
extern struct callgate_pseudo idttable[]; /* From locore.S. */ |
229 |
|
int i; |
230 |
|
|
231 |
/* We zero fill the IDT, so when/if an interrupt or exception in raised |
/* We zero fill the IDT, so when/if an interrupt or exception in raised |
232 |
that's not valid, a general protection exception will be generated. */ |
that's not valid, a general protection exception will be generated. */ |
233 |
memset (idt, 0, sizeof idt); |
memset (idt, 0, sizeof idt); |
234 |
|
|
235 |
|
for (i = 0; i < NCPUS; i++) |
236 |
|
{ |
237 |
|
gdttable [6 + i].doff = 7 + i; |
238 |
|
gdttable [6 + i].offset = (unsigned int) &ktss [i]; |
239 |
|
gdttable [6 + i].limorseg = (sizeof ktss [i]) - 1; |
240 |
|
gdttable [6 + i].szorwc = 0; |
241 |
|
gdttable [6 + i].access = ACC_PL_K | ACC_TSS; |
242 |
|
} |
243 |
|
|
244 |
/* Convert from pseudo format to real segment format. */ |
/* Convert from pseudo format to real segment format. */ |
245 |
convert_descriptors (gdt, gdttable, SZGDT); |
convert_descriptors (gdt, gdttable, SZGDT); |
246 |
convert_descriptors (ldt, ldttable, SZLDT); |
convert_descriptors (ldt, ldttable, SZLDT); |