Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/pm.c

    rd242cb6 r0f17bff  
    4141#include <panic.h>
    4242#include <arch/mm/page.h>
     43#include <mm/km.h>
     44#include <mm/frame.h>
    4345#include <mm/slab.h>
    4446#include <memstr.h>
    4547#include <arch/boot/boot.h>
    4648#include <interrupt.h>
     49#include <arch/cpu.h>
    4750
    4851/*
     
    5154
    5255/*
    53  * 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
     56 * 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
    5558 * whole memory. One is for code and one is for data.
    5659 *
    57  * One is for GS register which holds pointer to the TLS thread
    58  * 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.
    5962 */
    6063descriptor_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        },
    75105        /* VESA Init descriptor */
    76106#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        }
    79119#endif
    80120};
     
    82122static idescriptor_t idt[IDT_ITEMS];
    83123
    84 static tss_t tss;
     124static tss_t tss0;
    85125
    86126tss_t *tss_p = NULL;
     
    95135{
    96136        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;
    99139}
    100140
     
    217257}
    218258
    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 
    243259void pm_init(void)
    244260{
     
    265281                 * the heap hasn't been initialized so far.
    266282                 */
    267                 tss_p = &tss;
    268         }
    269         else {
     283                tss_p = &tss0;
     284        } else {
    270285                tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
    271286                if (!tss_p)
     
    288303        tr_load(GDT_SELECTOR(TSS_DES));
    289304       
    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);
    304310}
    305311
Note: See TracChangeset for help on using the changeset viewer.