blob: eb44042c4e1e7b9e8aa245d6893989542cb0bc04 [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @file
2
3Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13 Paging.c
14
15Abstract:
16
17Revision 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
52VOID
53EnableNullPointerProtection (
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
70VOID
71Ia32Create4KPageTables (
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
111VOID
112Ia32Create4MPageTables (
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
148VOID *
149PreparePageTable (
150 VOID *PageNumberTop,
151 UINT8 SizeOfMemorySpace
152 )
153/*++
154Description:
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}