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 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 272 _ModuleEntryPoint ( 273 IN EFILDRHANDOFF *Handoff 274 ) 275 { 276 DxeInit(Handoff); 277 return EFI_SUCCESS; 278 } 279