mirror of https://github.com/acidanthera/audk.git
279 lines
10 KiB
C
279 lines
10 KiB
C
/** @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 = %p, Length = %x\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, (UINTN) 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;
|
|
}
|