1 /** @file
2
3 Copyright (c) 2006 - 2011, 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 DxeInit.c
14
15 Abstract:
16
17 Revision History:
18
19 **/
20
21 #include "DxeIpl.h"
22
23 #include "LegacyTable.h"
24 #include "HobGeneration.h"
25 #include "PpisNeededByDxeCore.h"
26 #include "Debug.h"
27
28 /*
29 --------------------------------------------------------
30 Memory Map: (XX=32,64)
31 --------------------------------------------------------
32 0x0
33 IVT
34 0x400
35 BDA
36 0x500
37
38 0x7C00
39 BootSector
40 0x10000
41 EfiLdr (relocate by efiXX.COM)
42 0x15000
43 Efivar.bin (Load by StartXX.COM)
44 0x20000
45 StartXX.COM (E820 table, Temporary GDT, Temporary IDT)
46 0x21000
47 EfiXX.COM (Temporary Interrupt Handler)
48 0x22000
49 EfiLdr.efi + DxeIpl.Z + DxeMain.Z + BFV.Z
50 0x86000
51 MemoryFreeUnder1M (For legacy driver DMA)
52 0x90000
53 Temporary 4G PageTable for X64 (6 page)
54 0x9F800
55 EBDA
56 0xA0000
57 VGA
58 0xC0000
59 OPROM
60 0xE0000
61 FIRMEWARE
62 0x100000 (1M)
63 Temporary Stack (1M)
64 0x200000
65
66 MemoryAbove1MB.PhysicalStart <-----------------------------------------------------+
67 ... |
68 ... |
69 <- Phit.EfiMemoryBottom -------------------+ |
70 HOB | |
71 <- Phit.EfiFreeMemoryBottom | |
72 | MemoryFreeAbove1MB.ResourceLength
73 <- Phit.EfiFreeMemoryTop ------+ | |
74 MemoryDescriptor (For ACPINVS, ACPIReclaim) | 4M = CONSUMED_MEMORY |
75 | | |
76 Permament 4G PageTable for IA32 or MemoryAllocation | |
77 Permament 64G PageTable for X64 | | |
78 <------------------------------+ | |
79 Permament Stack (0x20 Pages = 128K) | |
80 <- Phit.EfiMemoryTop ----------+-----------+---------------+
81 NvFV (64K) |
82 MMIO
83 FtwFV (128K) |
84 <----------------------------------------------------------+<---------+
85 DxeCore | |
86 DxeCore |
87 DxeIpl | Allocated in EfiLdr
88 <----------------------------------------------------------+ |
89 BFV MMIO |
90 <- Top of Free Memory reported by E820 --------------------+<---------+
91 ACPINVS or
92 ACPIReclaim or
93 Reserved
94 <- Memory Top on RealMemory
95
96 0x100000000 (4G)
97
98 MemoryFreeAbove4G.Physicalstart <--------------------------------------------------+
99 |
100 |
101 MemoryFreeAbove4GB.ResourceLength
102 |
103 |
104 <--------------------------------------------------+
105 */
106
107 VOID
108 EnterDxeMain (
109 IN VOID *StackTop,
110 IN VOID *DxeCoreEntryPoint,
111 IN VOID *Hob,
112 IN VOID *PageTable
113 );
114
115 VOID
DxeInit(IN EFILDRHANDOFF * Handoff)116 DxeInit (
117 IN EFILDRHANDOFF *Handoff
118 )
119 /*++
120
121 Routine Description:
122
123 This is the entry point after this code has been loaded into memory.
124
125 Arguments:
126
127
128 Returns:
129
130 Calls into EFI Firmware
131
132 --*/
133 {
134 VOID *StackTop;
135 VOID *StackBottom;
136 VOID *PageTableBase;
137 VOID *MemoryTopOnDescriptor;
138 VOID *MemoryDescriptor;
139 VOID *NvStorageBase;
140 EFILDRHANDOFF HandoffCopy;
141
142 CopyMem ((VOID*) &HandoffCopy, (VOID*) Handoff, sizeof (EFILDRHANDOFF));
143 Handoff = &HandoffCopy;
144
145 ClearScreen();
146
147 PrintString (
148 "Enter DxeIpl ...\n"
149 "Handoff:\n"
150 "Handoff.BfvBase = %p, BfvLength = %x\n"
151 "Handoff.DxeIplImageBase = %p, DxeIplImageSize = %x\n"
152 "Handoff.DxeCoreImageBase = %p, DxeCoreImageSize = %x\n",
153 Handoff->BfvBase, Handoff->BfvSize,
154 Handoff->DxeIplImageBase, Handoff->DxeIplImageSize,
155 Handoff->DxeCoreImageBase, Handoff->DxeCoreImageSize
156 );
157
158 //
159 // Hob Generation Guild line:
160 // * Don't report FV as physical memory
161 // * MemoryAllocation Hob should only cover physical memory
162 // * Use ResourceDescriptor Hob to report physical memory or Firmware Device and they shouldn't be overlapped
163 PrintString ("Prepare Cpu HOB information ...\n");
164 PrepareHobCpu ();
165
166 //
167 // 1. BFV
168 //
169 PrintString ("Prepare BFV HOB information ...\n");
170 PrepareHobBfv (Handoff->BfvBase, Handoff->BfvSize);
171
172 //
173 // 2. Updates Memory information, and get the top free address under 4GB
174 //
175 PrintString ("Prepare Memory HOB information ...\n");
176 MemoryTopOnDescriptor = PrepareHobMemory (Handoff->MemDescCount, Handoff->MemDesc);
177
178 //
179 // 3. Put [NV], [Stack], [PageTable], [MemDesc], [HOB] just below the [top free address under 4GB]
180 //
181
182 // 3.1 NV data
183 PrintString ("Prepare NV Storage information ...\n");
184 NvStorageBase = PrepareHobNvStorage (MemoryTopOnDescriptor);
185 PrintString ("NV Storage Base = %p\n", NvStorageBase);
186 // 3.2 Stack
187 StackTop = NvStorageBase;
188 StackBottom = PrepareHobStack (StackTop);
189 PrintString ("Stack Top=0x%x, Stack Bottom=0x%x\n", StackTop, StackBottom);
190 // 3.3 Page Table
191 PageTableBase = PreparePageTable (StackBottom, gHob->Cpu.SizeOfMemorySpace);
192 // 3.4 MemDesc (will be used in PlatformBds)
193 MemoryDescriptor = PrepareHobMemoryDescriptor (PageTableBase, Handoff->MemDescCount, Handoff->MemDesc);
194 // 3.5 Copy the Hob itself to EfiMemoryBottom, and update the PHIT Hob
195 PrepareHobPhit (StackTop, MemoryDescriptor);
196
197 //
198 // 4. Register the memory occupied by DxeCore and DxeIpl together as DxeCore
199 //
200 PrintString ("Prepare DxeCore memory Hob ...\n");
201 PrepareHobDxeCore (
202 Handoff->DxeCoreEntryPoint,
203 (EFI_PHYSICAL_ADDRESS)(UINTN)Handoff->DxeCoreImageBase,
204 (UINTN)Handoff->DxeIplImageBase + (UINTN)Handoff->DxeIplImageSize - (UINTN)Handoff->DxeCoreImageBase
205 );
206
207 PrepareHobLegacyTable (gHob);
208
209 PreparePpisNeededByDxeCore (gHob);
210
211 CompleteHobGeneration ();
212
213 //
214 // Print Hob Info
215 //
216 ClearScreen();
217 PrintString (
218 "HobStart = %p\n"
219 "Memory Top = %lx, Bottom = %lx\n"
220 "Free Memory Top = %lx, Bottom = %lx\n"
221 "NvStorageFvb = %lx, Length = %lx\n"
222 "BfvResource = %lx, Length = %lx\n"
223 "NvStorageFvResource = %lx, Length = %lx\n"
224 "NvStorage = %lx, Length = %lx\n"
225 "NvFtwFvResource = %lx, Length = %lx\n"
226 "NvFtwWorking = %lx, Length = %lx\n"
227 "NvFtwSpare = %lx, Length = %lx\n"
228 "Stack = %lx, StackLength = %lx\n"
229 "PageTable = %p\n"
230 "MemoryFreeUnder1MB = %lx, MemoryFreeUnder1MBLength = %lx\n"
231 "MemoryAbove1MB = %lx, MemoryAbove1MBLength = %lx\n"
232 "MemoryAbove4GB = %lx, MemoryAbove4GBLength = %lx\n"
233 "DxeCore = %lx, DxeCoreLength = %lx\n"
234 "MemoryAllocation = %lx, MemoryLength = %lx\n"
235 "$",
236 gHob,
237 gHob->Phit.EfiMemoryTop, gHob->Phit.EfiMemoryBottom,
238 gHob->Phit.EfiFreeMemoryTop, gHob->Phit.EfiFreeMemoryBottom,
239 gHob->NvStorageFvb.FvbInfo.Entries[0].Base, gHob->NvFtwFvb.FvbInfo.Entries[0].Length,
240 gHob->BfvResource.PhysicalStart, gHob->BfvResource.ResourceLength,
241 gHob->NvStorageFvResource.PhysicalStart, gHob->NvStorageFvResource.ResourceLength,
242 gHob->NvStorage.FvbInfo.Entries[0].Base, gHob->NvStorage.FvbInfo.Entries[0].Length,
243 gHob->NvFtwFvResource.PhysicalStart, gHob->NvFtwFvResource.ResourceLength,
244 gHob->NvFtwWorking.FvbInfo.Entries[0].Base, gHob->NvFtwWorking.FvbInfo.Entries[0].Length,
245 gHob->NvFtwSpare.FvbInfo.Entries[0].Base, gHob->NvFtwSpare.FvbInfo.Entries[0].Length,
246 gHob->Stack.AllocDescriptor.MemoryBaseAddress, gHob->Stack.AllocDescriptor.MemoryLength,
247 PageTableBase,
248 gHob->MemoryFreeUnder1MB.PhysicalStart, gHob->MemoryFreeUnder1MB.ResourceLength,
249 gHob->MemoryAbove1MB.PhysicalStart, gHob->MemoryAbove1MB.ResourceLength,
250 gHob->MemoryAbove4GB.PhysicalStart, gHob->MemoryAbove4GB.ResourceLength,
251 gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress, gHob->DxeCore.MemoryAllocationHeader.MemoryLength,
252 gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress, gHob->MemoryAllocation.AllocDescriptor.MemoryLength
253 );
254
255 ClearScreen();
256 PrintString (
257 "\n\n\n\n\n\n\n\n\n\n"
258 " WELCOME TO EFI WORLD!\n"
259 );
260
261 EnterDxeMain (StackTop, Handoff->DxeCoreEntryPoint, gHob, PageTableBase);
262 PrintString ("Fail to enter DXE main!\n");
263
264 //
265 // Should never get here
266 //
267 CpuDeadLoop ();
268 }
269
270 EFI_STATUS
271 EFIAPI
_ModuleEntryPoint(IN EFILDRHANDOFF * Handoff)272 _ModuleEntryPoint (
273 IN EFILDRHANDOFF *Handoff
274 )
275 {
276 DxeInit(Handoff);
277 return EFI_SUCCESS;
278 }
279