Home | History | Annotate | Download | only in Ia32
      1 /** @file
      2 
      3 Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13   Paging.c
     14 
     15 Abstract:
     16 
     17 Revision History:
     18 
     19 **/
     20 
     21 #include "DxeIpl.h"
     22 #include "HobGeneration.h"
     23 #include "VirtualMemory.h"
     24 #include "Debug.h"
     25 
     26 #define EFI_PAGE_SIZE_4K      0x1000
     27 #define EFI_PAGE_SIZE_4M      0x400000
     28 
     29 //
     30 // Create 4G 4M-page table
     31 // PDE (31:22)   :  1024 entries
     32 //
     33 #define EFI_MAX_ENTRY_NUM     1024
     34 
     35 #define EFI_PDE_ENTRY_NUM     EFI_MAX_ENTRY_NUM
     36 
     37 #define EFI_PDE_PAGE_NUM      1
     38 
     39 #define EFI_PAGE_NUMBER_4M    (EFI_PDE_PAGE_NUM)
     40 
     41 //
     42 // Create 4M 4K-page table
     43 // PTE (21:12)   :  1024 entries
     44 //
     45 #define EFI_PTE_ENTRY_NUM     EFI_MAX_ENTRY_NUM
     46 #define EFI_PTE_PAGE_NUM      1
     47 
     48 #define EFI_PAGE_NUMBER_4K    (EFI_PTE_PAGE_NUM)
     49 
     50 #define EFI_PAGE_NUMBER       (EFI_PAGE_NUMBER_4M + EFI_PAGE_NUMBER_4K)
     51 
     52 VOID
     53 EnableNullPointerProtection (
     54   UINT8 *PageTable
     55   )
     56 {
     57   IA32_PAGE_TABLE_ENTRY_4K                      *PageTableEntry4KB;
     58 
     59   PageTableEntry4KB = (IA32_PAGE_TABLE_ENTRY_4K *)((UINTN)PageTable + EFI_PAGE_NUMBER_4M * EFI_PAGE_SIZE_4K);
     60 
     61   //
     62   // Fill in the Page Table entries
     63   // Mark 0~4K as not present
     64   //
     65   PageTableEntry4KB->Bits.Present = 0;
     66 
     67   return ;
     68 }
     69 
     70 VOID
     71 Ia32Create4KPageTables (
     72   UINT8 *PageTable
     73   )
     74 {
     75   UINT64                                        PageAddress;
     76   UINTN                                         PTEIndex;
     77   IA32_PAGE_DIRECTORY_ENTRY_4K                  *PageDirectoryEntry4KB;
     78   IA32_PAGE_TABLE_ENTRY_4K                      *PageTableEntry4KB;
     79 
     80   PageAddress = 0;
     81 
     82   //
     83   //  Page Table structure 2 level 4K.
     84   //
     85   //  Page Table 4K  : PageDirectoryEntry4K      : bits 31-22
     86   //                   PageTableEntry            : bits 21-12
     87   //
     88 
     89   PageTableEntry4KB = (IA32_PAGE_TABLE_ENTRY_4K *)((UINTN)PageTable + EFI_PAGE_NUMBER_4M * EFI_PAGE_SIZE_4K);
     90   PageDirectoryEntry4KB = (IA32_PAGE_DIRECTORY_ENTRY_4K *)((UINTN)PageTable);
     91 
     92   PageDirectoryEntry4KB->Uint32 = (UINT32)(UINTN)PageTableEntry4KB;
     93   PageDirectoryEntry4KB->Bits.ReadWrite = 0;
     94   PageDirectoryEntry4KB->Bits.Present = 1;
     95   PageDirectoryEntry4KB->Bits.MustBeZero = 1;
     96 
     97   for (PTEIndex = 0; PTEIndex < EFI_PTE_ENTRY_NUM; PTEIndex++, PageTableEntry4KB++) {
     98     //
     99     // Fill in the Page Table entries
    100     //
    101     PageTableEntry4KB->Uint32 = (UINT32)PageAddress;
    102     PageTableEntry4KB->Bits.ReadWrite = 1;
    103     PageTableEntry4KB->Bits.Present = 1;
    104 
    105     PageAddress += EFI_PAGE_SIZE_4K;
    106   }
    107 
    108   return ;
    109 }
    110 
    111 VOID
    112 Ia32Create4MPageTables (
    113   UINT8 *PageTable
    114   )
    115 {
    116   UINT32                                        PageAddress;
    117   UINT8                                         *TempPageTable;
    118   UINTN                                         PDEIndex;
    119   IA32_PAGE_TABLE_ENTRY_4M                      *PageDirectoryEntry4MB;
    120 
    121   TempPageTable = PageTable;
    122 
    123   PageAddress = 0;
    124 
    125   //
    126   //  Page Table structure 1 level 4MB.
    127   //
    128   //  Page Table 4MB : PageDirectoryEntry4M      : bits 31-22
    129   //
    130 
    131   PageDirectoryEntry4MB = (IA32_PAGE_TABLE_ENTRY_4M *)TempPageTable;
    132 
    133   for (PDEIndex = 0; PDEIndex < EFI_PDE_ENTRY_NUM; PDEIndex++, PageDirectoryEntry4MB++) {
    134     //
    135     // Fill in the Page Directory entries
    136     //
    137     PageDirectoryEntry4MB->Uint32 = (UINT32)PageAddress;
    138     PageDirectoryEntry4MB->Bits.ReadWrite = 1;
    139     PageDirectoryEntry4MB->Bits.Present = 1;
    140     PageDirectoryEntry4MB->Bits.MustBe1 = 1;
    141 
    142     PageAddress += EFI_PAGE_SIZE_4M;
    143   }
    144 
    145   return ;
    146 }
    147 
    148 VOID *
    149 PreparePageTable (
    150   VOID  *PageNumberTop,
    151   UINT8 SizeOfMemorySpace
    152   )
    153 /*++
    154 Description:
    155   Generate pagetable below PageNumberTop,
    156   and return the bottom address of pagetable for putting other things later.
    157 --*/
    158 {
    159   VOID *PageNumberBase;
    160 
    161   PageNumberBase = (VOID *)((UINTN)PageNumberTop - EFI_PAGE_NUMBER * EFI_PAGE_SIZE_4K);
    162   ZeroMem (PageNumberBase, EFI_PAGE_NUMBER * EFI_PAGE_SIZE_4K);
    163 
    164   Ia32Create4MPageTables (PageNumberBase);
    165   Ia32Create4KPageTables (PageNumberBase);
    166   //
    167   // Not enable NULL Pointer Protection if using INTX call
    168   //
    169 //  EnableNullPointerProtection (PageNumberBase);
    170 
    171   return PageNumberBase;
    172 }
    173