/**
* FlashDriver.c - AMI Flash Driver
*
* Module: FlashDriver.efi (0256)
* Source: AmiModulePkg/FlashDriver/
*
* This is a UEFI DXE Runtime Driver that manages SPI flash programming
* for BIOS flash chips. It detects flash devices, maps them to MMIO,
* and provides a protocol interface for read/write/erase operations.
*
* Build environment: VS2015 DEBUG, X64
* Source tree: e:\hs\
*/
#include "FlashDriver.h"
// ============================================================================
// Global Variables
// ============================================================================
EFI_HANDLE ImageHandle; // gImageHandle 0x7218
UINT64 SystemTable; // gST 0x7208
UINT64 BootServices; // gBS 0x7210
UINT64 RuntimeServices; // gRT 0x7220
UINT64 RuntimeServices_0; // 0x7228
UINT64 BootServices_0; // 0x7240
UINT64 gDS; // DxeServices 0x7250
UINT64 gPciUsra; // MmPciBase 0x7258
UINT64 RuntimeServices_1; // 0x73B8
UINT64 gPciExpressBaseAddress; // 0x7280
//
// PCIe Segment/Bus cache
//
UINTN mPciExpressRegistration; // 0x7288
UINT64 mPcieSegBusTable; // qword_7270 0x7270
UINT64 mPcieSegBusTableCount; // qword_7278 0x7278
BOOLEAN mEfiGoneVirtual; // byte_7268 0x7268
//
// Flash protocol & state
//
UINT64 FlashProtocolHandle; // qword_72F8 0x72F8
UINT64 FlashProtocolNotify; // qword_72F0 0x72F0
UINT64 FlashProtocolDb; // qword_72E8 0x72E8
UINT64 FlashProtocolInterface; // qword_7290 0x7290
UINT64 FlashRegionTable; // qword_7318 0x7318
UINT64 FlashRegionTableEnd; // qword_7308 0x7308
UINT32 FlashRegionEntrySize; // dword_7310 0x7310
UINT32 FlashRegionTableSize; // dword_7300 0x7300
UINT64 FlashSpinelBase; // qword_7338 0x7338
UINT8 FlashSpinelState; // byte_7332 0x7332
UINT8 FlashSpinelIndex; // byte_7331 0x7331
//
// Event notification handles
//
UINT64 VirtualAddressChangeEvent; // qword_7230 0x7230
UINT64 VirtualAddressChangeRelEvent; // qword_7238 0x7238
UINT64 RuntimeNotifyEventHandle; // qword_73B0 0x73B0
UINT64 RuntimeNotifyEventHandle2; // qword_73C0 0x73C0
//------------------------------------------------------------------------------
// Function Implementations
//------------------------------------------------------------------------------
/**
* ModuleEntryPoint - Standard UEFI DXE entry point.
*/
EFI_STATUS
EFIAPI
ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
FlashDriverInit(ImageHandle, SystemTable);
Status = FlashDriverEntry();
if (EFI_ERROR(Status)) {
FlashDriverUnload();
}
return Status;
}
/**
* FlashDriverInit - Core initialization.
*
* Initializes all UEFI tables (gImageHandle, gST, gBS, gRT),
* registers runtime virtual address change events,
* locates the MM PCI Base protocol,
* installs the Flash Protocol,
* registers runtime notification.
*/
EFI_STATUS
EFIAPI
FlashDriverInit (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
gImageHandle = ImageHandle;
if (ImageHandle == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
51,
"gImageHandle != ((void *) 0)");
}
gST = (UINT64)SystemTable;
if (SystemTable == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
57,
"gST != ((void *) 0)");
}
gBS = (UINT64)SystemTable->BootServices;
if (gBS == 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
63,
"gBS != ((void *) 0)");
}
RuntimeServices = (UINT64)SystemTable->RuntimeServices;
if (RuntimeServices == 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c",
47,
"gRT != ((void *) 0)");
}
BootServices_0 = (UINT64)SystemTable->BootServices;
RuntimeServices_0 = (UINT64)SystemTable->RuntimeServices;
//
// Register virtual address change notify events
//
gBS->CreateEvent(
EVT_NOTIFY_VIRTUAL_ADDRESS_CHANGE,
TPL_NOTIFY,
NotifyVirtualAddressChangeNull,
NULL,
&VirtualAddressChangeEvent);
gBS->CreateEvent(
EVT_NOTIFY_SIGNAL_ALL,
TPL_NOTIFY,
NotifyVirtualAddressChangeRelease,
NULL,
&VirtualAddressChangeRelEvent);
//
// Locate DxeServicesTable
//
Status = EfiGetSystemConfigurationTable(&gEfiDxeServicesTableGuid, &gDS);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
64,
"!EFI_ERROR (Status)");
}
if (gDS == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
65,
"gDS != ((void *) 0)");
}
//
// Locate MmPciBase protocol
//
if (gPciUsra == NULL) {
Status = gBS->LocateProtocol(&gEfiMmPciBaseProtocolGuid, NULL, &gPciUsra);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
52,
"!EFI_ERROR (Status)");
}
if (gPciUsra == NULL) {
DebugAssert(
"e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
53,
"mPciUsra != ((void *) 0)");
}
}
FlashProtocolInstall();
if (RuntimeServices == 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
95,
"gRT != ((void *) 0)");
}
if (gBS == 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
96,
"gBS != ((void *) 0)");
}
RuntimeNotifyEvent();
gBS->SetTimer(RuntimeNotifyEventHandle, TimerPeriodic, 0);
gBS->SetTimer(RuntimeNotifyEventHandle2, TimerPeriodic, 0);
return EFI_SUCCESS;
}
/**
* FlashDriverEntry - Driver entry.
*
* Creates notification events, installs Flash Protocol.
*/
EFI_STATUS
FlashDriverEntry (VOID)
{
EFI_STATUS Status;
UINT64 Handle;
EFI_GUID FlashProtocolGuid = FLASH_PROTOCOL_GUID;
Status = gBS->CreateEvent(
EVT_NOTIFY_SIGNAL_ALL,
TPL_NOTIFY,
FlashSpinelHandler,
NULL,
&Handle);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\AmiModulePkg\\FlashDriver\\FlashDxe.c",
63,
"!EFI_ERROR (Status)");
}
if (CS_ != 0) {
Status = 0x8000000000000009ULL;
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\AmiModulePkg\\FlashDriver\\Flash.c",
715,
"!EFI_ERROR (Status)");
} else {
aCs[4] = 0;
CS_ = (UINT64)aCs;
Status = EFI_SUCCESS;
CS__0 = (UINT64)aCs;
}
qword_70C8 = -1;
dword_7204 = 1;
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\AmiModulePkg\\FlashDriver\\FlashDxe.c",
66,
"!EFI_ERROR (Status)");
}
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&FlashProtocolGuid,
NULL,
NULL);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\AmiModulePkg\\FlashDriver\\FlashDxe.c",
69,
"!EFI_ERROR (Status)");
}
return Status;
}
/**
* FlashDriverUnload - Driver unload.
*
* Frees events, PCIe memory, flash regions.
*/
EFI_STATUS
FlashDriverUnload (VOID)
{
EFI_STATUS Status;
Status = gBS->CloseEvent(VirtualAddressChangeEvent);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\AmiModulePkg\\FlashDriver\\FlashDriver\\DEBUG\\AutoGen.c",
557,
"!EFI_ERROR (Status)");
}
if (mPcieSegBusTable != 0) {
FlashFreePciExpressMmio();
}
Status = gBS->CloseEvent(PciExpressNotifyEvent);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\MdePkg\\Library\\DxeRuntimePciExpressLib\\PciExpressLib.c",
178,
"!EFI_ERROR (Status)");
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\AmiModulePkg\\FlashDriver\\FlashDriver\\DEBUG\\AutoGen.c",
560,
"!EFI_ERROR (Status)");
}
Status = gBS->CloseEvent(RuntimeNotifyEventHandle);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
153,
"!EFI_ERROR (Status)");
}
Status = gBS->CloseEvent(RuntimeNotifyEventHandle2);
if (EFI_ERROR(Status)) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
156,
"!EFI_ERROR (Status)");
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugAssert(
"e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\AmiModulePkg\\FlashDriver\\FlashDriver\\DEBUG\\AutoGen.c",
563,
"!EFI_ERROR (Status)");
}
gBS->CloseEvent(VirtualAddressChangeEvent);
gBS->CloseEvent(VirtualAddressChangeRelEvent);
return EFI_SUCCESS;
}
/**
* FlashSpinelHandler - Spinel state machine callback.
*
* Notifies runtime services about completed flash operations.
*/
VOID
FlashSpinelHandler (VOID)
{
for (i = 0; i < FlashSpinelIndex; i++) {
gRT->ConvertPointer(0, &byte_73E0[16 * i]);
}
gRT->ConvertPointer(0, &CS__0);
}
/**
* FlashProtocolInstall - Flash Protocol Implementation.
*
* Locates flash config descriptor (from HOB or system config table),
* allocates region entries, installs the Flash Protocol.
*/
EFI_STATUS
EFIAPI
FlashProtocolInstall (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable,
...
)
{
EFI_STATUS Status;
UINT64 FlashConfigTable;
FLASH_DESCRIPTOR *Descriptor;
FLASH_REGION_ENTRY *RegionEntry;
UINT32 RegionSize;
UINTN EntryCount;
Status = EfiGetSystemConfigurationTable(&gEfiFlashProtocolGuid, &FlashConfigTable);
if (EFI_ERROR(Status)) {
for (Descriptor = HobGetNext(NULL);
Descriptor != NULL && !CompareGuid(&gEfiFlashProtocolGuid, Descriptor + 8);
Descriptor = HobGetNext(Descriptor + *(UINT16 *)(Descriptor + 2))) {
;
}
} else {
Descriptor = (FLASH_DESCRIPTOR *)FlashConfigTable;
}
if (Descriptor != NULL) {
RegionSize = *(UINT16 *)(Descriptor + 2) - sizeof(FLASH_DESCRIPTOR) + 8;
EntryCount = *(UINT32 *)(Descriptor + 32);
FlashRegionEntrySize = *((UINT32 *)Descriptor + 7);
FlashRegionTableSize = FlashRegionEntrySize * DivU64x32(RegionSize, EntryCount);
RegionEntry = (FLASH_REGION_ENTRY *)AllocatePool(0, FlashRegionTableSize);
if (RegionEntry != NULL) {
RegionEntry = InternalZeroMem(RegionEntry, FlashRegionTableSize);
}
FlashRegionTable = (UINT64)RegionEntry;
if (RegionEntry != NULL) {
FlashRegionTableEnd = (UINT64)RegionEntry + FlashRegionTableSize;
if ((UINT64)(Descriptor + 40) < (UINT64)Descriptor + *(UINT16 *)(Descriptor + 2)) {
do {
gBS->CopyMem(RegionEntry, Descriptor + 40 + 8, FlashRegionEntrySize);
Descriptor += EntryCount;
RegionEntry += FlashRegionEntrySize;
} while ((UINT64)Descriptor < Descriptor + *(UINT16 *)(Descriptor + 2));
}
if (EFI_ERROR(Status)) {
RegionEntry = AllocatePool(0, *(UINT16 *)(Descriptor + 2));
gBS->CopyMem(RegionEntry, Descriptor, *(UINT16 *)(Descriptor + 2));
gBS->InstallConfigurationTable(&gEfiFlashProtocolGuid, RegionEntry);
}
}
}
gBS->CreateEvent(
EVT_NOTIFY_VIRTUAL_ADDRESS_CHANGE,
TPL_NOTIFY,
FlashVirtualAddressNotify,
NULL,
&VirtualAddressChangeEvent);
gBS->CreateEvent(
EVT_NOTIFY_SIGNAL_ALL,
TPL_NOTIFY,
FlashFreePciExpressMmio,
NULL,
&RuntimeNotifyEventHandle);
return EFI_SUCCESS;
}
/**
* FlashVirtualAddressNotify - Runtime address conversion.
*
* Converts all physical flash addresses to virtual addresses
* during OS runtime transition.
*/
VOID
FlashVirtualAddressNotify (VOID)
{
FLASH_REGION_ENTRY *Entry;
UINT64 (*DispatchFn)(UINT64, UINT64 *);
UINTN Index;
if (FlashSpinelBase != 0 && FlashSpinelState != 1) {
FlashSpinelState = 1;
gRT->ConvertPointer(0, FlashSpinelBase);
gRT->ConvertPointer(0, FlashSpinelBase + 8);
gRT->ConvertPointer(0, FlashSpinelBase + 16);
gRT->ConvertPointer(0, FlashSpinelBase + 24);
gRT->ConvertPointer(0, FlashSpinelBase + 32);
gRT->ConvertPointer(0, FlashSpinelBase + 40);
gRT->ConvertPointer(0, FlashSpinelBase + 48);
gRT->ConvertPointer(0, FlashSpinelBase + 56);
gRT->ConvertPointer(0, FlashSpinelBase + 64);
gRT->ConvertPointer(0, FlashSpinelBase + 80);
gRT->ConvertPointer(0, &FlashSpinelBase);
gRT->ConvertPointer(0, &unk_7108);
gRT->ConvertPointer(0, &qword_7100);
for (Index = 0; Index < FlashSpinelIndex; Index++) {
gRT->ConvertPointer(0, &FlashSpinelBase + Index);
}
DispatchFn = (UINT64 (*)(UINT64, UINT64 *))&off_67E0;
while (*DispatchFn != NULL) {
if ((*DispatchFn)(gImageHandle, &FlashSpinelBase)) {
break;
}
DispatchFn++;
}
gRT->ConvertPointer(0, &FlashSpinelBase);
}
if (FlashRegionTable != 0) {
Entry = (FLASH_REGION_ENTRY *)FlashRegionTable;
do {
gRT->ConvertPointer(0, &Entry->VirtualAddress);
Entry = FlashTableNextEntry(Entry);
} while (Entry != NULL);
gRT->ConvertPointer(0, &FlashRegionTable);
gRT->ConvertPointer(0, &FlashRegionTableEnd);
}
}
/**
* FlashFreePciExpressMmio - Frees PCIe MMIO mappings.
*/
VOID
FlashFreePciExpressMmio (VOID)
{
FLASH_REGION_ENTRY *Entry;
Entry = (FLASH_REGION_ENTRY *)FlashRegionTable;
if (Entry == 0) {
return;
}
do {
gRT->ConvertPointer(0, &Entry->VirtualAddress);
Entry = FlashTableNextEntry(Entry);
} while (Entry != NULL);
gRT->ConvertPointer(0, &FlashRegionTable);
gRT->ConvertPointer(0, &FlashRegionTableEnd);
}
/**
* FlashTableNextEntry - Get next flash region entry.
*/
FLASH_REGION_ENTRY *
FlashTableNextEntry (
IN FLASH_REGION_ENTRY *Entry
)
{
FLASH_REGION_ENTRY *Next;
Next = (FLASH_REGION_ENTRY *)((UINT8 *)Entry + 16);
if ((UINT64)Next >= FlashRegionTableEnd) {
return NULL;
}
if (Next->BaseAddress == 0 && Next->VirtualAddress == 0) {
return NULL;
}
return Next;
}
/**
* FlashDeviceProbe - SPI flash device probing.
*
* Dispatches to probe functions registered in off_67E0.
*/
EFI_STATUS
FlashDeviceProbe (
IN UINTN FlashDeviceIndex
)
{
UINT64 (*DispatchEntry)(UINT64, UINT64 *);
UINT64 Result;
DispatchEntry = (UINT64 (*)(UINT64, UINT64 *))&off_67E0;
do {
if (*DispatchEntry == NULL) {
break;
}
Result = (*DispatchEntry)(FlashDeviceIndex, &FlashSpinelBase);
DispatchEntry++;
} while (!Result);
return 0;
}
/**
* GetDebugOutputInterface - Locate EFI Debug Protocol.
*/
VOID *
GetDebugOutputInterface (VOID)
{
VOID *DebugInterface;
UINTN BufferSize;
DebugInterface = (VOID *)qword_7248;
if (DebugInterface == NULL) {
if (BootServices_0 != 0) {
BufferSize = (UINTN)(*gBS->AllocatePool)(31);
(*gBS->FreePool)(BufferSize);
if (BufferSize <= 0x10) {
Status = gBS->LocateProtocol(&gEfiDebugProtocolGuid, NULL, &DebugInterface);
if (EFI_ERROR(Status)) {
DebugInterface = NULL;
}
qword_7248 = (UINT64)DebugInterface;
}
}
}
return DebugInterface;
}
/**
* DebugPrint - Formatted debug print via CMOS level.
*/
VOID
EFIAPI
DebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
)
{
VOID *DebugInterface;
UINTN DebugLevelMask;
UINT8 CmosIndex, CmosValue;
va_list Marker;
va_start(Marker, Format);
DebugInterface = GetDebugOutputInterface();
DebugLevelMask = 0;
if (DebugInterface != NULL) {
CmosIndex = __inbyte(0x70);
__outbyte(0x70, CmosIndex & 0x80 | 0x4B);
CmosValue = __inbyte(0x71);
if (CmosValue > 3) {
CmosValue = 3;
}
DebugLevelMask = CmosValue - 1;
if ((UINT8)(CmosValue - 1) <= 0xFD) {
if (CmosValue == 1) {
DebugLevelMask = 2147483652LL;
}
}
if (DebugLevelMask & ErrorLevel) {
((VOID (*)(UINTN, CONST CHAR8 *, va_list))DebugInterface->DebugPrint)(
ErrorLevel, Format, Marker);
}
}
}
/**
* DebugAssert - UEFI assertion handler.
*/
VOID
EFIAPI
DebugAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
)
{
VOID *DebugInterface;
DebugInterface = GetDebugOutputInterface();
if (DebugInterface != NULL) {
((VOID (*)(VOID *))DebugInterface->DebugAssert)(DebugInterface);
}
}
/**
* EfiGetSystemConfigurationTable - Locate config table by GUID.
*/
EFI_STATUS
EfiGetSystemConfigurationTable (
IN EFI_GUID *TableGuid,
OUT VOID **Table
)
{
UINTN Index;
if (TableGuid == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
97,
"TableGuid != ((void *) 0)");
}
if (Table == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
98,
"Table != ((void *) 0)");
}
*Table = NULL;
if (gST->NumberOfTableEntries == 0) {
return EFI_NOT_FOUND;
}
for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
if (CompareGuid(TableGuid, &gST->ConfigurationTable[Index].VendorGuid)) {
*Table = gST->ConfigurationTable[Index].VendorTable;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/**
* CompareGuid - Compare two GUIDs.
*/
BOOLEAN
CompareGuid (
IN EFI_GUID *Guid1,
IN EFI_GUID *Guid2
)
{
return (ReadUint64FromBuffer(Guid1) == ReadUint64FromBuffer(Guid2)) &&
(ReadUint64FromBuffer((UINT8 *)Guid1 + 8) ==
ReadUint64FromBuffer((UINT8 *)Guid2 + 8));
}
/**
* ReadUint64FromBuffer - Read a UINT64 from buffer.
*/
UINT64
ReadUint64FromBuffer (
IN VOID *Buffer
)
{
return *((volatile UINT64 *)Buffer);
}
/**
* NotifyVirtualAddressChangeNull - Dummy handler.
*/
VOID
NotifyVirtualAddressChangeNull (VOID)
{
BootServices_0 = 0;
}
/**
* NotifyVirtualAddressChangeRelease - Release handler.
*/
VOID
NotifyVirtualAddressChangeRelease (VOID)
{
if (qword_7248 != 0) {
gRT->ConvertPointer(0, &qword_7248);
}
}
/**
* NullFunction - No-op placeholder.
*/
VOID
NullFunction (VOID)
{
}
/**
* RuntimeNotifyEvent - Register runtime notification.
*/
EFI_STATUS
RuntimeNotifyEvent (VOID)
{
EFI_STATUS Status;
Status = gRT->ConvertPointer(0, &RuntimeServices_1);
byte_7268 = 1;
return Status;
}
/**
* RuntimeFreePages - Free runtime pages.
*/
VOID
RuntimeFreePages (VOID)
{
UINTN Index;
VOID *Table;
Table = (VOID *)mPcieSegBusTable;
if (Table != NULL) {
if (mPcieSegBusTableCount != 0) {
for (Index = 0; Index < mPcieSegBusTableCount; Index++) {
gRT->ConvertPointer(0, (UINT64)Table + Index * 16 + 8);
}
}
gRT->ConvertPointer(0, &mPcieSegBusTable);
}
}
/**
* PciExpressGetAddress - Translate PCIe cfg address to MMIO.
*/
UINTN
EFIAPI
PciExpressGetAddress (
IN UINTN Address
)
{
UINTN Translated;
UINTN PageOffset;
UINTN Index;
if ((Address & 0xFFFFFFFFF0000000ULL) != 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\DxeRuntimePciExpressLib\\PciExpressLib.c",
203,
"((Address) & ~0xfffffff) == 0");
}
Translated = gPciExpressBaseAddress + Address;
if (mEfiGoneVirtual) {
PageOffset = Translated & 0xFFF;
if (*(UINT64 *)(mPcieSegBusTable + 16 * mPciExpressRegistration) ==
(Translated & 0xFFFFFFFFFFFFF000ULL)) {
return *(UINT64 *)(mPcieSegBusTable + 16 * mPciExpressRegistration + 8) + PageOffset;
}
if (mPcieSegBusTableCount == 0) {
goto Fail;
}
for (Index = 0; Index < mPcieSegBusTableCount; Index++) {
if (*(UINT64 *)(mPcieSegBusTable + Index * 16) ==
(Translated & 0xFFFFFFFFFFFFF000ULL)) {
mPciExpressRegistration = Index;
return *(UINT64 *)(mPcieSegBusTable + Index * 16 + 8) + PageOffset;
}
}
Fail:
DebugAssert(
"e:\\hs\\MdePkg\\Library\\DxeRuntimePciExpressLib\\PciExpressLib.c",
246,
"((BOOLEAN)(0==1))");
__debugbreak();
}
return Translated;
}
/**
* IoWrite16 - Write to I/O port (value 0x500).
*/
UINT16
IoWrite16 (
IN UINT16 *Address
)
{
if (((UINTN)Address & 1) != 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
183,
"(Address & 1) == 0");
}
*Address = 0x500;
return 0x500;
}
/**
* IoRead32 - Read I/O port DWORD value.
*/
UINT32
IoRead32 (
IN UINT16 Port
)
{
if ((Port & 3) != 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLibMsc.c",
193,
"(Port & 3) == 0");
}
return __indword(Port);
}
/**
* DivU64x32 - 64/32 unsigned division.
*/
UINT64
DivU64x32 (
IN UINT64 Dividend,
IN UINT32 Divisor
)
{
if (Divisor == 0) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseLib\\DivU64x32.c",
43,
"Divisor != 0");
}
return Dividend / Divisor;
}
/**
* InternalZeroMem - Zero-fill memory.
*/
VOID *
EFIAPI
InternalZeroMem (
IN VOID *Buffer,
IN UINTN Length
)
{
if (Length == 0) {
return Buffer;
}
if (Buffer == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
53,
"Buffer != ((void *) 0)");
}
if (Length > -Buffer) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
54,
"Length <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)Buffer + 1)");
}
return sub_10C0(Buffer, Length);
}
/**
* InternalCopyMem - Copy memory buffer.
*/
VOID *
EFIAPI
InternalCopyMem (
OUT VOID *Destination,
IN CONST VOID *Source,
IN UINTN Length
)
{
UINTN DestEnd, SrcEnd;
if (Length != 0) {
if (Length - 1 > (UINTN)(-1) - (UINTN)Destination) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
56,
"(Length - 1) <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)DestinationBuffer)");
}
if (Length - 1 > (UINTN)(-1) - (UINTN)Source) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
57,
"(Length - 1) <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)SourceBuffer)");
}
if (Destination != Source) {
return sub_1000(Destination, Source, Length);
}
}
return Destination;
}
/**
* AllocatePool - Allocate memory pool.
*/
VOID *
AllocatePool (
IN UINT32 EntryType,
IN UINTN Size
)
{
EFI_STATUS Status;
VOID *Buffer;
Buffer = NULL;
Status = gBS->AllocatePool(EfiRuntimeServicesData, Size, &Buffer);
if (EFI_ERROR(Status)) {
return NULL;
}
return Buffer;
}
/**
* FlashIsReadyGet - Get flash ready state.
*/
BOOLEAN
FlashIsReadyGet (VOID)
{
BOOLEAN WasReady;
WasReady = byte_7368;
if (!byte_7368) {
byte_7368 = 1;
}
return WasReady;
}
/**
* FlashSpiFlashCmd - Send SPI flash command.
*/
EFI_STATUS
FlashSpiFlashCmd (
IN VOID *CmdBuffer
)
{
byte_7350 = 1;
return ((EFI_RUNTIME_SERVICES *)CmdBuffer)->ConvertPointer(0, 29168);
}
/**
* NotifySetDsNull - Sets DXE Services to null.
*/
VOID
NotifySetDsNull (VOID)
{
gDS = 0;
}
/**
* CpuPause - CPU pause instruction.
*/
VOID
CpuPause (VOID)
{
_mm_pause();
}
/**
* HOB_GET_NEXT - Walk HOB list for type 4.
*/
VOID *
HobGetNext (
IN VOID *HobStart
)
{
UINT16 *HobPtr;
HobPtr = (UINT16 *)HobStart;
if (HobPtr == NULL) {
DebugAssert(
"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
108,
"HobStart != ((void *) 0)");
}
while (TRUE) {
if (*HobPtr == 0xFFFF) {
return NULL;
}
if (*HobPtr == 4) {
break;
}
HobPtr = (UINT16 *)((UINT8 *)HobPtr + HobPtr[1]);
}
return HobPtr;
}