Home | History | Annotate | Download | only in CpuDxe
      1 /** @file
      2   C based implemention of IA32 interrupt handling only
      3   requiring a minimal assembly interrupt entry point.
      4 
      5   Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "CpuDxe.h"
     17 #include "CpuGdt.h"
     18 
     19 //
     20 // Global descriptor table (GDT) Template
     21 //
     22 STATIC GDT_ENTRIES GdtTemplate = {
     23   //
     24   // NULL_SEL
     25   //
     26   {
     27     0x0,            // limit 15:0
     28     0x0,            // base 15:0
     29     0x0,            // base 23:16
     30     0x0,            // type
     31     0x0,            // limit 19:16, flags
     32     0x0,            // base 31:24
     33   },
     34   //
     35   // LINEAR_SEL
     36   //
     37   {
     38     0x0FFFF,        // limit 15:0
     39     0x0,            // base 15:0
     40     0x0,            // base 23:16
     41     0x092,          // present, ring 0, data, read/write
     42     0x0CF,          // page-granular, 32-bit
     43     0x0,
     44   },
     45   //
     46   // LINEAR_CODE_SEL
     47   //
     48   {
     49     0x0FFFF,        // limit 15:0
     50     0x0,            // base 15:0
     51     0x0,            // base 23:16
     52     0x09F,          // present, ring 0, code, execute/read, conforming, accessed
     53     0x0CF,          // page-granular, 32-bit
     54     0x0,
     55   },
     56   //
     57   // SYS_DATA_SEL
     58   //
     59   {
     60     0x0FFFF,        // limit 15:0
     61     0x0,            // base 15:0
     62     0x0,            // base 23:16
     63     0x093,          // present, ring 0, data, read/write, accessed
     64     0x0CF,          // page-granular, 32-bit
     65     0x0,
     66   },
     67   //
     68   // SYS_CODE_SEL
     69   //
     70   {
     71     0x0FFFF,        // limit 15:0
     72     0x0,            // base 15:0
     73     0x0,            // base 23:16
     74     0x09A,          // present, ring 0, code, execute/read
     75     0x0CF,          // page-granular, 32-bit
     76     0x0,
     77   },
     78   //
     79   // SPARE4_SEL
     80   //
     81   {
     82     0x0,            // limit 15:0
     83     0x0,            // base 15:0
     84     0x0,            // base 23:16
     85     0x0,            // type
     86     0x0,            // limit 19:16, flags
     87     0x0,            // base 31:24
     88   },
     89   //
     90   // LINEAR_DATA64_SEL
     91   //
     92   {
     93     0x0FFFF,        // limit 15:0
     94     0x0,            // base 15:0
     95     0x0,            // base 23:16
     96     0x092,          // present, ring 0, data, read/write
     97     0x0CF,          // page-granular, 32-bit
     98     0x0,
     99   },
    100   //
    101   // LINEAR_CODE64_SEL
    102   //
    103   {
    104     0x0FFFF,        // limit 15:0
    105     0x0,            // base 15:0
    106     0x0,            // base 23:16
    107     0x09A,          // present, ring 0, code, execute/read
    108     0x0AF,          // page-granular, 64-bit code
    109     0x0,            // base (high)
    110   },
    111   //
    112   // SPARE5_SEL
    113   //
    114   {
    115     0x0,            // limit 15:0
    116     0x0,            // base 15:0
    117     0x0,            // base 23:16
    118     0x0,            // type
    119     0x0,            // limit 19:16, flags
    120     0x0,            // base 31:24
    121   },
    122 };
    123 
    124 /**
    125   Initialize Global Descriptor Table.
    126 
    127 **/
    128 VOID
    129 InitGlobalDescriptorTable (
    130   VOID
    131   )
    132 {
    133   GDT_ENTRIES *gdt;
    134   IA32_DESCRIPTOR gdtPtr;
    135 
    136   //
    137   // Allocate Runtime Data for the GDT
    138   //
    139   gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
    140   ASSERT (gdt != NULL);
    141   gdt = ALIGN_POINTER (gdt, 8);
    142 
    143   //
    144   // Initialize all GDT entries
    145   //
    146   CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate));
    147 
    148   //
    149   // Write GDT register
    150   //
    151   gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt;
    152   gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
    153   AsmWriteGdtr (&gdtPtr);
    154 
    155   //
    156   // Update selector (segment) registers base on new GDT
    157   //
    158   SetCodeSelector ((UINT16)CPU_CODE_SEL);
    159   SetDataSelectors ((UINT16)CPU_DATA_SEL);
    160 }
    161 
    162