Changes in kernel/arch/ia32/src/pm.c [d242cb6:0f17bff] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/pm.c
rd242cb6 r0f17bff 41 41 #include <panic.h> 42 42 #include <arch/mm/page.h> 43 #include <mm/km.h> 44 #include <mm/frame.h> 43 45 #include <mm/slab.h> 44 46 #include <memstr.h> 45 47 #include <arch/boot/boot.h> 46 48 #include <interrupt.h> 49 #include <arch/cpu.h> 47 50 48 51 /* … … 51 54 52 55 /* 53 * We have no use for segmentation so we set up flat mode. In this54 * mode, we use, for each privilege level, two segments spanning the56 * We don't have much use for segmentation so we set up flat mode. 57 * In this mode, we use, for each privilege level, two segments spanning the 55 58 * whole memory. One is for code and one is for data. 56 59 * 57 * One is for GS register which holds pointer to the TLS thread58 * structure in it's base.60 * One special segment apart of that is for the GS register which holds 61 * a pointer to the VREG page in its base. 59 62 */ 60 63 descriptor_t gdt[GDT_ITEMS] = { 61 /* NULL descriptor */ 62 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 63 /* KTEXT descriptor */ 64 { 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, 65 /* KDATA descriptor */ 66 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, 67 /* UTEXT descriptor */ 68 { 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, 69 /* UDATA descriptor */ 70 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, 71 /* TSS descriptor - set up will be completed later */ 72 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 73 /* TLS descriptor */ 74 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, 64 [NULL_DES] = { 65 0 66 }, 67 [KTEXT_DES] = { 68 .limit_0_15 = 0xffff, 69 .limit_16_19 = 0xf, 70 .access = AR_PRESENT | AR_CODE | DPL_KERNEL, 71 .special = 1, 72 .granularity = 1 73 }, 74 [KDATA_DES] = { 75 .limit_0_15 = 0xffff, 76 .limit_16_19 = 0xf, 77 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 78 .special = 1, 79 .granularity = 1 80 }, 81 [UTEXT_DES] = { 82 .limit_0_15 = 0xffff, 83 .limit_16_19 = 0xf, 84 .access = AR_PRESENT | AR_CODE | DPL_USER, 85 .special = 1, 86 .granularity = 1 87 }, 88 [UDATA_DES] = { 89 .limit_0_15 = 0xffff, 90 .limit_16_19 = 0xf, 91 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 92 .special = 1, 93 .granularity = 1 94 }, 95 [TSS_DES] = { /* set up will be completed later */ 96 0, 97 }, 98 [VREG_DES] = { /* will be reinitialized later */ 99 .limit_0_15 = 0xffff, 100 .limit_16_19 = 0xf, 101 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 102 .special = 1, 103 .granularity = 1 104 }, 75 105 /* VESA Init descriptor */ 76 106 #ifdef CONFIG_FB 77 { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | AR_READABLE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }, 78 { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 } 107 [VESA_INIT_CODE_DES] = { 108 .limit_0_15 = 0xffff, 109 .limit_16_19 = 0xf, 110 .base_16_23 = VESA_INIT_SEGMENT >> 12, 111 .access = AR_PRESENT | AR_CODE | AR_READABLE | DPL_KERNEL 112 }, 113 [VESA_INIT_DATA_DES] = { 114 .limit_0_15 = 0xffff, 115 .limit_16_19 = 0xf, 116 .base_16_23 = VESA_INIT_SEGMENT >> 12, 117 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL 118 } 79 119 #endif 80 120 }; … … 82 122 static idescriptor_t idt[IDT_ITEMS]; 83 123 84 static tss_t tss ;124 static tss_t tss0; 85 125 86 126 tss_t *tss_p = NULL; … … 95 135 { 96 136 d->base_0_15 = base & 0xffff; 97 d->base_16_23 = ( (base)>> 16) & 0xff;98 d->base_24_31 = ( (base)>> 24) & 0xff;137 d->base_16_23 = (base >> 16) & 0xff; 138 d->base_24_31 = (base >> 24) & 0xff; 99 139 } 100 140 … … 217 257 } 218 258 219 /* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */220 static void clean_IOPL_NT_flags(void)221 {222 asm volatile (223 "pushfl\n"224 "pop %%eax\n"225 "and $0xffff8fff, %%eax\n"226 "push %%eax\n"227 "popfl\n"228 ::: "eax"229 );230 }231 232 /* Clean AM(18) flag in CR0 register */233 static void clean_AM_flag(void)234 {235 asm volatile (236 "mov %%cr0, %%eax\n"237 "and $0xfffbffff, %%eax\n"238 "mov %%eax, %%cr0\n"239 ::: "eax"240 );241 }242 243 259 void pm_init(void) 244 260 { … … 265 281 * the heap hasn't been initialized so far. 266 282 */ 267 tss_p = &tss; 268 } 269 else { 283 tss_p = &tss0; 284 } else { 270 285 tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); 271 286 if (!tss_p) … … 288 303 tr_load(GDT_SELECTOR(TSS_DES)); 289 304 290 clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ 291 clean_AM_flag(); /* Disable alignment check */ 292 } 293 294 void set_tls_desc(uintptr_t tls) 295 { 296 ptr_16_32_t cpugdtr; 297 descriptor_t *gdt_p; 298 299 gdtr_store(&cpugdtr); 300 gdt_p = (descriptor_t *) cpugdtr.base; 301 gdt_setbase(&gdt_p[TLS_DES], tls); 302 /* Reload gdt register to update GS in CPU */ 303 gdtr_load(&cpugdtr); 305 /* Disable I/O on nonprivileged levels and clear NT flag. */ 306 write_eflags(read_eflags() & ~(EFLAGS_IOPL | EFLAGS_NT)); 307 308 /* Disable alignment check */ 309 write_cr0(read_cr0() & ~CR0_AM); 304 310 } 305 311
Note:
See TracChangeset
for help on using the changeset viewer.