• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
EnableNullPointerProtection(UINT8 * PageTable)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
Ia32Create4KPageTables(UINT8 * PageTable)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
Ia32Create4MPageTables(UINT8 * PageTable)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 *
PreparePageTable(VOID * PageNumberTop,UINT8 SizeOfMemorySpace)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