init.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 791 行 · 第 1/2 页
C
791 行
#ifdef EFI_BOOTSHELL
//
// Global Data
//
STATIC BOOLEAN ShellToolsLoaded = FALSE;
VOID
PlStartShell (
VOID
)
{
if (ShellToolsLoaded == FALSE) {
PlLoadShellTools();
PlLoadShellDebugTools();
PlLoadShellAdditionalTools();
ShellToolsLoaded = TRUE;
}
PlLoadShell();
}
#endif
STATIC
VOID
PlInitializeTables (
IN UINTN FunctionId
)
/*++
Routine Description:
Initialization function called to obtain and update any
global table information or entry points that are in:
SystemTable
SystemTable->BootServices
SystemTAble->RuntimeServices
Arguments:
None
Returns:
Tables set and updated
--*/
{
//
// Initialize the platform table
//
PlTable.EmulateLoad = NULL;
PlTable.IdleLoop = PlIdleLoop;
PlTable.SetInterruptState = PlSetInterruptState;
PlTable.FlushCache = RtPlCacheFlush;
PlTable.SetVirtualAddressMap = RtPlSetVirtualAddressMap;
PlTable.SI_HandoffState = NULL;
PlTable.EI_ReturnState = NULL;
//
// Call the EFI FW's entry point and get back the initial
// Firwmare and SystemTable
//
EFIEntryPoint (&PlTable, &FW, &ST);
BS = ST->BootServices;
RT = ST->RuntimeServices;
//
// Update / provide any entries in the boot services table
// The core EFI firmware does not provide the following
// entries in the boot services table:
// Stal
//
BS->Stall = RtPlStall;
BS->SetWatchdogTimer = PlSetWatchdogTimer;
//
// Update / provide any entries in the runtime service table.
// The core EFI firmware does not provide the following
// entries in the runtime services table:
RT->ResetSystem = RtPlResetSystem;
RT->GetTime = RtPlGetTime;
RT->SetTime = RtPlSetTime;
RT->GetWakeupTime = RtPlGetWakeupTime;
RT->SetWakeupTime = RtPlSetWakeupTime;
ST->NumberOfTableEntries = 0;
ST->ConfigurationTable = NULL;
//
// Done with table initializations
//
}
STATIC
VOID
PlInstallMemoryMap (
IN UINTN FunctionId,
IN UINTN NoDesc,
IN EFI_MEMORY_DESCRIPTOR *Desc
)
/*++
Routine Description:
Called to initialize the memory map descriptors for
the system's memory map.
N.B. The FW requires that the first call be of type
"ConventialMemory".
N.B. The FW requires that page 0 in the map is not
not ConventialMemory. (Note the emulator can work
around this by reporting page 0 as BootServicesData
memory if needed. The page is then not used at
Boot Services time, but it available in the memory
map for later use)
Arguments:
NoDesc - Number of desc in Desc
Desc - The passed in memory map
Returns:
Memory map descriptors added
--*/
{
UINTN Index;
UINTN Index1;
UINTN BestIndex;
UINT64 End;
UINT64 BestSize;
for (Index=0; Index < NoDesc; Index++) {
if (Desc[Index].Type == EfiACPIReclaimMemory ||
Desc[Index].Type == EfiACPIMemoryNVS ||
(Desc[Index].Attribute & EFI_MEMORY_RUNTIME) ) {
if (Desc[Index].PhysicalStart & 0x1fff) {
for (Index1=0; Index1 < NoDesc; Index1++) {
if (Desc[Index1].Type == EfiConventionalMemory && Desc[Index1].NumberOfPages > 0) {
End = Desc[Index1].PhysicalStart + LShiftU64 (Desc[Index1].NumberOfPages, EFI_PAGE_SHIFT);
if (End == Desc[Index].PhysicalStart) {
Desc[Index1].NumberOfPages--;
Desc[Index].PhysicalStart -= EFI_PAGE_SIZE;
Desc[Index].NumberOfPages++;
}
}
}
}
if (Desc[Index].NumberOfPages & 1) {
End = Desc[Index].PhysicalStart + LShiftU64 (Desc[Index].NumberOfPages, EFI_PAGE_SHIFT);
for (Index1=0; Index1 < NoDesc; Index1++) {
if (Desc[Index1].Type == EfiConventionalMemory && Desc[Index1].NumberOfPages > 0) {
if (End == Desc[Index1].PhysicalStart) {
Desc[Index].NumberOfPages++;
Desc[Index1].NumberOfPages--;
Desc[Index1].PhysicalStart += EFI_PAGE_SIZE;
}
}
}
}
}
}
//
// Find the largest available free memory descriptor
// and add it first
//
BestIndex = NoDesc;
BestSize = 0;
for (Index=0; Index < NoDesc; Index += 1) {
if (Desc[Index].Type == EfiConventionalMemory &&
Desc[Index].NumberOfPages > BestSize) {
BestIndex = Index;
BestSize = Desc[Index].NumberOfPages;
}
}
ASSERT (BestIndex < NoDesc);
FW->AddMemoryDescriptor (
Desc[BestIndex].Type,
Desc[BestIndex].PhysicalStart,
Desc[BestIndex].NumberOfPages,
Desc[BestIndex].Attribute
);
//
// Now add all remaining information to the memory map
//
for (Index=0; Index < NoDesc; Index++) {
if (Index != BestIndex && Desc[Index].NumberOfPages > 0) {
FW->AddMemoryDescriptor (
Desc[Index].Type,
Desc[Index].PhysicalStart,
Desc[Index].NumberOfPages,
Desc[Index].Attribute
);
}
}
}
STATIC
VOID
PlInstallBaseDevices (
IN UINTN FunctionId,
IN UINTN NvramBanks,
IN UINTN NvramSize
)
/*++
Routine Description:
Add handles to the base devices here. In particular
the console devices, internal nvram device(s), and
the timer tick handler.
Variable store support is not enabled at this time.
(The firware needs the nvram & system volume devices
to enable such support)
Arguments:
None
Returns:
Base device handles added
--*/
{
EFI_DEVICE_PATH *DevicePath;
EFI_HANDLE Handle;
EFI_STATUS Status;
UINT64 IoPortBase;
//
//
// First add a device(s) to handle device_io request
// (this is done since the next devices may need to access
// their IO space)
//
if (LibGetSalIoPortMapping (&IoPortBase) != EFI_SUCCESS) {
//
// BugBug: If you can't find it in the SAL System Table take a guess.
// If this guess is wrong you will plant in the ASSERT in the stall
// routine. It will look like the timer is not ticking since IOs are
// not working.
//
IoPortBase = 0x0000ffffc000000;
}
//
// EFI is defined to be in physical mode. Thus we must flip bit 63 to
// make the IO cycles be uncacheable.
//
IoPortBase |= 0x8000000000000000;
PlInstallDefaultIoDevice (
BiosRootDevicePath,
0x8000000000000000, // Force non cachable access
IoPortBase
);
//
// Set up the GlobalIoFncs global to point to global memory/io/pci space
//
DevicePath = BiosRootDevicePath;
Status = BS->LocateDevicePath (&DeviceIoProtocol, &DevicePath, &Handle);
if (!EFI_ERROR(Status)) {
Status = BS->HandleProtocol (Handle, &DeviceIoProtocol, (VOID *)&GlobalIoFncs);
}
ASSERT (!EFI_ERROR(Status));
//
// Initialize to PCI Root Bus List
//
InitializePciRootBusList (&PciRootBusList);
//
// Add SAL callback NVRAM store.
//
PlInitNvVarStoreFlash (
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
NvramSize, NvramBanks
);
//
// Install the Unicode string device. This device supports
// case insensitive comparisons of Unicode strings.
//
PlInitializeUnicodeStringDevice();
}
STATIC
VOID
PlIdleLoop (
IN BOOLEAN Polling
)
{
}
STATIC
VOID
PlExitBootServices (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Signal handlers for ExitBootServices event
Arguments:
Event type
Context fo the event
Returns:
--*/
{
//
// Clear non-runtime pointer
//
PlTable.EmulateLoad = NULL;
PlTable.IdleLoop = NULL;
PlTable.SetInterruptState = NULL;
// EFI f/w takes care of boot service's table
//
// Cancel Timer
//
PlTimer(ID_SALCB_TIMER_CANCEL, 0, NULL);
}
VOID
TimerCallBack (
IN UINTN ElapsedTime
)
/*++
Routine Description:
Timer callback . Called by SAL whenever the timer period expires
Arguments:
ElapsedTime in msec
Returns:
None
--*/
{
EFI_TPL OldTpl;
OldTpl = BS->RaiseTPL(TPL_HIGH_LEVEL);
//
// Inform the firmware of an "timer interrupt". The time expired
// since the last call is 10,000 times the number of ms. (or 100ns units)
//
FW->TickHandler(ElapsedTime*10000);
BS->RestoreTPL(OldTpl);
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?