bdsplatform.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,208 行 · 第 1/3 页
C
1,208 行
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. 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:
BdsPlatform.c
Abstract:
This file include all platform action which can be customized
by IBV/OEM.
--*/
#include "BdsPlatform.h"
#include "EfiPrintLib.h"
#include "String.h"
#include "Language.h"
#include "FrontPage.h"
#include EFI_GUID_DEFINITION (SmBios)
#include EFI_GUID_DEFINITION (Acpi)
#include EFI_GUID_DEFINITION (Mps)
#include EFI_GUID_DEFINITION (PciExpressBaseAddress)
CHAR16 mFirmwareVendor[] = L"TianoCore.org";
extern BOOLEAN gConnectAllHappened;
//
// BDS Platform Functions
//
VOID
GetSystemTablesFromHob (
VOID
)
/*++
Routine Description:
Find GUID'ed HOBs that contain EFI_PHYSICAL_ADDRESS of ACPI, SMBIOS, MPs tables
Arguments:
None
Returns:
None.
--*/
{
EFI_STATUS Status;
EFI_HOB_HANDOFF_INFO_TABLE *HobList;
UINTN Size;
EFI_PHYSICAL_ADDRESS *Table;
//
// Get Hob List
//
Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, (VOID *) &HobList);
if (EFI_ERROR (Status)) {
return;
}
//
// If there is an ACPI table in the HOB add it to the EFI System table
//
Status = GetNextGuidHob (&HobList, &gEfiAcpi20TableGuid, &Table, &Size);
if (!EFI_ERROR (Status)) {
if (*Table != 0) {
gBS->InstallConfigurationTable (&gEfiAcpi20TableGuid, (VOID *)(UINTN)*Table);
}
}
Status = GetNextGuidHob (&HobList, &gEfiAcpiTableGuid, &Table, &Size);
if (!EFI_ERROR (Status)) {
if (*Table != 0) {
gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, (VOID *)(UINTN)*Table);
}
}
//
// If there is a SMBIOS table in the HOB add it to the EFI System table
//
Status = GetNextGuidHob (&HobList, &gEfiSmbiosTableGuid, &Table, &Size);
if (!EFI_ERROR (Status)) {
if (*Table != 0) {
gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, (VOID *)(UINTN)*Table);
}
}
//
// If there is a MPS table in the HOB add it to the EFI System table
//
Status = GetNextGuidHob (&HobList, &gEfiMpsTableGuid, &Table, &Size);
if (!EFI_ERROR (Status)) {
if (*Table != 0) {
gBS->InstallConfigurationTable (&gEfiMpsTableGuid, (VOID *)(UINTN)*Table);
}
}
}
#define EFI_LDR_MEMORY_DESCRIPTOR_GUID \
{ 0x7701d7e5, 0x7d1d, 0x4432, 0xa4, 0x68, 0x67, 0x3d, 0xab, 0x8a, 0xde, 0x60 }
EFI_GUID gEfiLdrMemoryDescriptorGuid = EFI_LDR_MEMORY_DESCRIPTOR_GUID;
#pragma pack(1)
typedef struct {
EFI_HOB_GUID_TYPE Hob;
UINTN MemDescCount;
EFI_MEMORY_DESCRIPTOR *MemDesc;
} MEMORY_DESC_HOB;
#pragma pack()
VOID
UpdateMemoryMap (
VOID
)
{
EFI_STATUS Status;
EFI_HOB_HANDOFF_INFO_TABLE *HobList;
UINTN Size;
VOID *Table;
MEMORY_DESC_HOB MemoryDescHob;
UINTN Index;
EFI_PHYSICAL_ADDRESS Memory;
//
// Get Hob List
//
Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, (VOID *) &HobList);
if (EFI_ERROR (Status)) {
return;
}
Status = GetNextGuidHob (&HobList, &gEfiLdrMemoryDescriptorGuid, &Table, &Size);
if (EFI_ERROR (Status)) {
return;
}
MemoryDescHob.MemDescCount = *(UINTN *)Table;
MemoryDescHob.MemDesc = *(EFI_MEMORY_DESCRIPTOR **)((UINTN)Table + sizeof(UINTN));
//
// Add ACPINVS, ACPIReclaim, and Reserved memory to MemoryMap
//
for (Index = 0; Index < MemoryDescHob.MemDescCount; Index++) {
if (MemoryDescHob.MemDesc[Index].PhysicalStart < 0x100000) {
continue;
}
if (MemoryDescHob.MemDesc[Index].PhysicalStart >= 0x100000000) {
continue;
}
if ((MemoryDescHob.MemDesc[Index].Type == EfiReservedMemoryType) ||
(MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) ||
(MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode) ||
(MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory) ||
(MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS)) {
DEBUG ((EFI_D_ERROR, "PhysicalStart - 0x%x, ", MemoryDescHob.MemDesc[Index].PhysicalStart));
DEBUG ((EFI_D_ERROR, "PageNumber - 0x%x, ", MemoryDescHob.MemDesc[Index].NumberOfPages));
DEBUG ((EFI_D_ERROR, "Type - 0x%x\n", MemoryDescHob.MemDesc[Index].Type));
if ((MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) ||
(MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode)) {
//
// Skip RuntimeSevicesData and RuntimeServicesCode, they are BFV
//
continue;
}
Status = gDS->AddMemorySpace (
EfiGcdMemoryTypeSystemMemory,
MemoryDescHob.MemDesc[Index].PhysicalStart,
LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT),
MemoryDescHob.MemDesc[Index].Attribute
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "AddMemorySpace fail!\n"));
if ((MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory) ||
(MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS)) {
//
// For EfiACPIReclaimMemory and EfiACPIMemoryNVS, it must success.
// For EfiReservedMemoryType, there maybe overlap. So skip check here.
//
// ASSERT_EFI_ERROR (Status);
}
continue;
}
Memory = MemoryDescHob.MemDesc[Index].PhysicalStart;
Status = gBS->AllocatePages (
AllocateAddress,
MemoryDescHob.MemDesc[Index].Type,
(UINTN)MemoryDescHob.MemDesc[Index].NumberOfPages,
&Memory
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "AllocatePages fail!\n"));
//
// For the page added, it must be allocated.
//
// ASSERT_EFI_ERROR (Status);
continue;
}
}
}
}
VOID
PlatformBdsInit (
IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData
)
/*++
Routine Description:
Platform Bds init. Incude the platform firmware vendor, revision
and so crc check.
Arguments:
PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance
Returns:
None.
--*/
{
//
// set firmwarevendor, here can be IBV/OEM customize
//
gST->FirmwareVendor = EfiLibAllocateRuntimeCopyPool (
sizeof (mFirmwareVendor),
&mFirmwareVendor
);
ASSERT (gST->FirmwareVendor != NULL);
gST->FirmwareRevision = EFI_FIRMWARE_REVISION;
//
// Fixup Tasble CRC after we updated Firmware Vendor and Revision
//
gBS->CalculateCrc32 ((VOID *) gST, sizeof (EFI_SYSTEM_TABLE), &gST->Hdr.CRC32);
//
// Initialize the platform specific string and language
//
InitializeStringSupport ();
InitializeLanguage (TRUE);
InitializeFrontPage (FALSE);
GetSystemTablesFromHob ();
UpdateMemoryMap ();
}
UINT64
GetPciExpressBaseAddressForRootBridge (
IN UINTN HostBridgeNumber,
IN UINTN RootBridgeNumber
)
/*++
Routine Description:
This routine is to get PciExpress Base Address for this RootBridge
Arguments:
HostBridgeNumber - The number of HostBridge
RootBridgeNumber - The number of RootBridge
Returns:
UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge
--*/
{
EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION *PciExpressBaseAddressInfo;
UINTN BufferSize;
UINT32 Index;
UINT32 Number;
VOID *HobList;
EFI_STATUS Status;
//
// Get Hob List from configuration table
//
Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
if (EFI_ERROR (Status)) {
return 0;
}
//
// Get PciExpressAddressInfo Hob
//
PciExpressBaseAddressInfo = NULL;
Status = GetNextGuidHob (&HobList, &gEfiPciExpressBaseAddressGuid, &PciExpressBaseAddressInfo, &BufferSize);
if (EFI_ERROR (Status)) {
return 0;
}
//
// Search the PciExpress Base Address in the Hob for current RootBridge
//
Number = (UINT32)(BufferSize / sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION));
for (Index = 0; Index < Number; Index++) {
if ((PciExpressBaseAddressInfo[Index].HostBridgeNumber == HostBridgeNumber) &&
(PciExpressBaseAddressInfo[Index].RootBridgeNumber == RootBridgeNumber)) {
return PciExpressBaseAddressInfo[Index].PciExpressBaseAddress;
}
}
//
// Do not find the PciExpress Base Address in the Hob
//
return 0;
}
VOID
PatchPciRootBridgeDevicePath (
IN UINTN HostBridgeNumber,
IN UINTN RootBridgeNumber,
IN PLATFORM_ROOT_BRIDGE_DEVICE_PATH *RootBridge
)
{
UINT64 PciExpressBase;
PciExpressBase = GetPciExpressBaseAddressForRootBridge (HostBridgeNumber, RootBridgeNumber);
if (PciExpressBase != 0) {
RootBridge->PciRootBridge.HID = EISA_PNP_ID(0x0A08);
}
}
EFI_STATUS
ConnectRootBridge (
VOID
)
/*++
Routine Description:
Connect RootBridge
Arguments:
None.
Returns:
EFI_SUCCESS - Connect RootBridge successfully.
EFI_STATUS - Connect RootBridge fail.
--*/
{
EFI_STATUS Status;
EFI_HANDLE RootHandle;
//
// Patch Pci Root Bridge Device Path
//
PatchPciRootBridgeDevicePath (0, 0, &gPlatformRootBridge0);
//
// Make all the PCI_IO protocols on PCI Seg 0 show up
//
BdsLibConnectDevicePath (gPlatformRootBridges[0]);
Status = gBS->LocateDevicePath (
&gEfiDevicePathProtocolGuid,
&gPlatformRootBridges[0],
&RootHandle
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
PrepareLpcBridgeDevicePath (
IN EFI_HANDLE DeviceHandle
)
/*++
Routine Description:
Add IsaKeyboard to ConIn,
add IsaSerial to ConOut, ConIn, ErrOut.
LPC Bridge: 06 01 00
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?