Changes in kernel/arch/ia32/src/pm.c [0f17bff:d242cb6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/pm.c
r0f17bff rd242cb6 41 41 #include <panic.h> 42 42 #include <arch/mm/page.h> 43 #include <mm/km.h>44 #include <mm/frame.h>45 43 #include <mm/slab.h> 46 44 #include <memstr.h> 47 45 #include <arch/boot/boot.h> 48 46 #include <interrupt.h> 49 #include <arch/cpu.h>50 47 51 48 /* … … 54 51 55 52 /* 56 * We don't have much use for segmentation so we set up flat mode.57 * In thismode, we use, for each privilege level, two segments spanning the53 * We have no use for segmentation so we set up flat mode. In this 54 * mode, we use, for each privilege level, two segments spanning the 58 55 * whole memory. One is for code and one is for data. 59 56 * 60 * One special segment apart of that is for the GS register which holds61 * a pointer to the VREG page in its base.57 * One is for GS register which holds pointer to the TLS thread 58 * structure in it's base. 62 59 */ 63 60 descriptor_t gdt[GDT_ITEMS] = { 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 }, 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 }, 105 75 /* VESA Init descriptor */ 106 76 #ifdef CONFIG_FB 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 } 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 } 119 79 #endif 120 80 }; … … 122 82 static idescriptor_t idt[IDT_ITEMS]; 123 83 124 static tss_t tss 0;84 static tss_t tss; 125 85 126 86 tss_t *tss_p = NULL; … … 135 95 { 136 96 d->base_0_15 = base & 0xffff; 137 d->base_16_23 = ( base>> 16) & 0xff;138 d->base_24_31 = ( base>> 24) & 0xff;97 d->base_16_23 = ((base) >> 16) & 0xff; 98 d->base_24_31 = ((base) >> 24) & 0xff; 139 99 } 140 100 … … 257 217 } 258 218 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 259 243 void pm_init(void) 260 244 { … … 281 265 * the heap hasn't been initialized so far. 282 266 */ 283 tss_p = &tss0; 284 } else { 267 tss_p = &tss; 268 } 269 else { 285 270 tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); 286 271 if (!tss_p) … … 303 288 tr_load(GDT_SELECTOR(TSS_DES)); 304 289 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); 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); 310 304 } 311 305
Note:
See TracChangeset
for help on using the changeset viewer.