/** @file | |
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
Module Name: | |
DxeInit.c | |
Abstract: | |
Revision History: | |
**/ | |
#include "DxeIpl.h" | |
#include "LegacyTable.h" | |
#include "HobGeneration.h" | |
#include "PpisNeededByDxeCore.h" | |
#include "Debug.h" | |
/* | |
-------------------------------------------------------- | |
Memory Map: (XX=32,64) | |
-------------------------------------------------------- | |
0x0 | |
IVT | |
0x400 | |
BDA | |
0x500 | |
0x7C00 | |
BootSector | |
0x10000 | |
EfiLdr (relocate by efiXX.COM) | |
0x15000 | |
Efivar.bin (Load by StartXX.COM) | |
0x20000 | |
StartXX.COM (E820 table, Temporary GDT, Temporary IDT) | |
0x21000 | |
EfiXX.COM (Temporary Interrupt Handler) | |
0x22000 | |
EfiLdr.efi + DxeIpl.Z + DxeMain.Z + BFV.Z | |
0x86000 | |
MemoryFreeUnder1M (For legacy driver DMA) | |
0x90000 | |
Temporary 4G PageTable for X64 (6 page) | |
0x9F800 | |
EBDA | |
0xA0000 | |
VGA | |
0xC0000 | |
OPROM | |
0xE0000 | |
FIRMEWARE | |
0x100000 (1M) | |
Temporary Stack (1M) | |
0x200000 | |
MemoryAbove1MB.PhysicalStart <-----------------------------------------------------+ | |
... | | |
... | | |
<- Phit.EfiMemoryBottom -------------------+ | | |
HOB | | | |
<- Phit.EfiFreeMemoryBottom | | | |
| MemoryFreeAbove1MB.ResourceLength | |
<- Phit.EfiFreeMemoryTop ------+ | | | |
MemoryDescriptor (For ACPINVS, ACPIReclaim) | 4M = CONSUMED_MEMORY | | |
| | | | |
Permament 4G PageTable for IA32 or MemoryAllocation | | | |
Permament 64G PageTable for X64 | | | | |
<------------------------------+ | | | |
Permament Stack (0x20 Pages = 128K) | | | |
<- Phit.EfiMemoryTop ----------+-----------+---------------+ | |
NvFV (64K) | | |
MMIO | |
FtwFV (128K) | | |
<----------------------------------------------------------+<---------+ | |
DxeCore | | | |
DxeCore | | |
DxeIpl | Allocated in EfiLdr | |
<----------------------------------------------------------+ | | |
BFV MMIO | | |
<- Top of Free Memory reported by E820 --------------------+<---------+ | |
ACPINVS or | |
ACPIReclaim or | |
Reserved | |
<- Memory Top on RealMemory | |
0x100000000 (4G) | |
MemoryFreeAbove4G.Physicalstart <--------------------------------------------------+ | |
| | |
| | |
MemoryFreeAbove4GB.ResourceLength | |
| | |
| | |
<--------------------------------------------------+ | |
*/ | |
VOID | |
EnterDxeMain ( | |
IN VOID *StackTop, | |
IN VOID *DxeCoreEntryPoint, | |
IN VOID *Hob, | |
IN VOID *PageTable | |
); | |
VOID | |
DxeInit ( | |
IN EFILDRHANDOFF *Handoff | |
) | |
/*++ | |
Routine Description: | |
This is the entry point after this code has been loaded into memory. | |
Arguments: | |
Returns: | |
Calls into EFI Firmware | |
--*/ | |
{ | |
VOID *StackTop; | |
VOID *StackBottom; | |
VOID *PageTableBase; | |
VOID *MemoryTopOnDescriptor; | |
VOID *MemoryDescriptor; | |
VOID *NvStorageBase; | |
EFILDRHANDOFF HandoffCopy; | |
CopyMem ((VOID*) &HandoffCopy, (VOID*) Handoff, sizeof (EFILDRHANDOFF)); | |
Handoff = &HandoffCopy; | |
ClearScreen(); | |
PrintString ( | |
"Enter DxeIpl ...\n" | |
"Handoff:\n" | |
"Handoff.BfvBase = %p, BfvLength = %x\n" | |
"Handoff.DxeIplImageBase = %p, DxeIplImageSize = %x\n" | |
"Handoff.DxeCoreImageBase = %p, DxeCoreImageSize = %x\n", | |
Handoff->BfvBase, Handoff->BfvSize, | |
Handoff->DxeIplImageBase, Handoff->DxeIplImageSize, | |
Handoff->DxeCoreImageBase, Handoff->DxeCoreImageSize | |
); | |
// | |
// Hob Generation Guild line: | |
// * Don't report FV as physical memory | |
// * MemoryAllocation Hob should only cover physical memory | |
// * Use ResourceDescriptor Hob to report physical memory or Firmware Device and they shouldn't be overlapped | |
PrintString ("Prepare Cpu HOB information ...\n"); | |
PrepareHobCpu (); | |
// | |
// 1. BFV | |
// | |
PrintString ("Prepare BFV HOB information ...\n"); | |
PrepareHobBfv (Handoff->BfvBase, Handoff->BfvSize); | |
// | |
// 2. Updates Memory information, and get the top free address under 4GB | |
// | |
PrintString ("Prepare Memory HOB information ...\n"); | |
MemoryTopOnDescriptor = PrepareHobMemory (Handoff->MemDescCount, Handoff->MemDesc); | |
// | |
// 3. Put [NV], [Stack], [PageTable], [MemDesc], [HOB] just below the [top free address under 4GB] | |
// | |
// 3.1 NV data | |
PrintString ("Prepare NV Storage information ...\n"); | |
NvStorageBase = PrepareHobNvStorage (MemoryTopOnDescriptor); | |
PrintString ("NV Storage Base = %p\n", NvStorageBase); | |
// 3.2 Stack | |
StackTop = NvStorageBase; | |
StackBottom = PrepareHobStack (StackTop); | |
PrintString ("Stack Top=0x%x, Stack Bottom=0x%x\n", StackTop, StackBottom); | |
// 3.3 Page Table | |
PageTableBase = PreparePageTable (StackBottom, gHob->Cpu.SizeOfMemorySpace); | |
// 3.4 MemDesc (will be used in PlatformBds) | |
MemoryDescriptor = PrepareHobMemoryDescriptor (PageTableBase, Handoff->MemDescCount, Handoff->MemDesc); | |
// 3.5 Copy the Hob itself to EfiMemoryBottom, and update the PHIT Hob | |
PrepareHobPhit (StackTop, MemoryDescriptor); | |
// | |
// 4. Register the memory occupied by DxeCore and DxeIpl together as DxeCore | |
// | |
PrintString ("Prepare DxeCore memory Hob ...\n"); | |
PrepareHobDxeCore ( | |
Handoff->DxeCoreEntryPoint, | |
(EFI_PHYSICAL_ADDRESS)(UINTN)Handoff->DxeCoreImageBase, | |
(UINTN)Handoff->DxeIplImageBase + (UINTN)Handoff->DxeIplImageSize - (UINTN)Handoff->DxeCoreImageBase | |
); | |
PrepareHobLegacyTable (gHob); | |
PreparePpisNeededByDxeCore (gHob); | |
CompleteHobGeneration (); | |
// | |
// Print Hob Info | |
// | |
ClearScreen(); | |
PrintString ( | |
"HobStart = %p\n" | |
"Memory Top = %lx, Bottom = %lx\n" | |
"Free Memory Top = %lx, Bottom = %lx\n" | |
"NvStorageFvb = %lx, Length = %lx\n" | |
"BfvResource = %lx, Length = %lx\n" | |
"NvStorageFvResource = %lx, Length = %lx\n" | |
"NvStorage = %lx, Length = %lx\n" | |
"NvFtwFvResource = %lx, Length = %lx\n" | |
"NvFtwWorking = %lx, Length = %lx\n" | |
"NvFtwSpare = %lx, Length = %lx\n" | |
"Stack = %lx, StackLength = %lx\n" | |
"PageTable = %p\n" | |
"MemoryFreeUnder1MB = %lx, MemoryFreeUnder1MBLength = %lx\n" | |
"MemoryAbove1MB = %lx, MemoryAbove1MBLength = %lx\n" | |
"MemoryAbove4GB = %lx, MemoryAbove4GBLength = %lx\n" | |
"DxeCore = %lx, DxeCoreLength = %lx\n" | |
"MemoryAllocation = %lx, MemoryLength = %lx\n" | |
"$", | |
gHob, | |
gHob->Phit.EfiMemoryTop, gHob->Phit.EfiMemoryBottom, | |
gHob->Phit.EfiFreeMemoryTop, gHob->Phit.EfiFreeMemoryBottom, | |
gHob->NvStorageFvb.FvbInfo.Entries[0].Base, gHob->NvFtwFvb.FvbInfo.Entries[0].Length, | |
gHob->BfvResource.PhysicalStart, gHob->BfvResource.ResourceLength, | |
gHob->NvStorageFvResource.PhysicalStart, gHob->NvStorageFvResource.ResourceLength, | |
gHob->NvStorage.FvbInfo.Entries[0].Base, gHob->NvStorage.FvbInfo.Entries[0].Length, | |
gHob->NvFtwFvResource.PhysicalStart, gHob->NvFtwFvResource.ResourceLength, | |
gHob->NvFtwWorking.FvbInfo.Entries[0].Base, gHob->NvFtwWorking.FvbInfo.Entries[0].Length, | |
gHob->NvFtwSpare.FvbInfo.Entries[0].Base, gHob->NvFtwSpare.FvbInfo.Entries[0].Length, | |
gHob->Stack.AllocDescriptor.MemoryBaseAddress, gHob->Stack.AllocDescriptor.MemoryLength, | |
PageTableBase, | |
gHob->MemoryFreeUnder1MB.PhysicalStart, gHob->MemoryFreeUnder1MB.ResourceLength, | |
gHob->MemoryAbove1MB.PhysicalStart, gHob->MemoryAbove1MB.ResourceLength, | |
gHob->MemoryAbove4GB.PhysicalStart, gHob->MemoryAbove4GB.ResourceLength, | |
gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress, gHob->DxeCore.MemoryAllocationHeader.MemoryLength, | |
gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress, gHob->MemoryAllocation.AllocDescriptor.MemoryLength | |
); | |
ClearScreen(); | |
PrintString ( | |
"\n\n\n\n\n\n\n\n\n\n" | |
" WELCOME TO EFI WORLD!\n" | |
); | |
EnterDxeMain (StackTop, Handoff->DxeCoreEntryPoint, gHob, PageTableBase); | |
PrintString ("Fail to enter DXE main!\n"); | |
// | |
// Should never get here | |
// | |
CpuDeadLoop (); | |
} | |
EFI_STATUS | |
EFIAPI | |
_ModuleEntryPoint ( | |
IN EFILDRHANDOFF *Handoff | |
) | |
{ | |
DxeInit(Handoff); | |
return EFI_SUCCESS; | |
} |