Ignore:
File:
1 edited

Legend:

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

    r0f17bff rd242cb6  
    4141#include <panic.h>
    4242#include <arch/mm/page.h>
    43 #include <mm/km.h>
    44 #include <mm/frame.h>
    4543#include <mm/slab.h>
    4644#include <memstr.h>
    4745#include <arch/boot/boot.h>
    4846#include <interrupt.h>
    49 #include <arch/cpu.h>
    5047
    5148/*
     
    5451
    5552/*
    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
     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
    5855 * whole memory. One is for code and one is for data.
    5956 *
    60  * One special segment apart of that is for the GS register which holds
    61  * 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.
    6259 */
    6360descriptor_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 },
    10575        /* VESA Init descriptor */
    10676#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 }
    11979#endif
    12080};
     
    12282static idescriptor_t idt[IDT_ITEMS];
    12383
    124 static tss_t tss0;
     84static tss_t tss;
    12585
    12686tss_t *tss_p = NULL;
     
    13595{
    13696        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;
    13999}
    140100
     
    257217}
    258218
     219/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
     220static 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 */
     233static 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
    259243void pm_init(void)
    260244{
     
    281265                 * the heap hasn't been initialized so far.
    282266                 */
    283                 tss_p = &tss0;
    284         } else {
     267                tss_p = &tss;
     268        }
     269        else {
    285270                tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
    286271                if (!tss_p)
     
    303288        tr_load(GDT_SELECTOR(TSS_DES));
    304289       
    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
     294void 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);
    310304}
    311305
Note: See TracChangeset for help on using the changeset viewer.