/** @file
SlotDataUpdateDxeLightningRidgeEXECB4 - PCIe Slot Data Configuration
This UEFI DXE driver provides slot data configuration for the LightningRidge EX
EC B4 platform. It publishes platform-specific slot table protocol interfaces
to the DXE protocol database during the entry point.
The driver performs the following:
- Initializes UEFI boot/runtime services table pointers
- Retrieves the HOB list from the system table
- Prints debug trace via UBA debug protocol
- Locates the platform slot protocol
- Installs slot configuration protocol interfaces with PCIe slot table data
Copyright (c) 2025, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SlotDataUpdateDxeLightningRidgeEXECB4.h"
//
// Global variables for UEFI system table pointers
//
EFI_HANDLE gImageHandle = NULL;
EFI_SYSTEM_TABLE *gSystemTable = NULL;
EFI_BOOT_SERVICES *gBootServices = NULL;
EFI_RUNTIME_SERVICES *gRuntimeServices = NULL;
//
// Cached protocol and HOB pointers
//
STATIC UBA_DEBUG_PROTOCOL *mDebugPrintProtocol = NULL;
STATIC VOID *mHobList = NULL;
//
// Platform slot table data - LightningRidge EX EC B4
// These tables define the PCIe slot configuration for the platform
//
STATIC CONST PLATFORM_SLOT_TABLE mSlotTableConfig1 = {
SLOT_TABLE_SIGNATURE, // Signature 'PSLT'
1, // Version
0xBB0, // GpioConfigBase
0x4B0, // SlotConfigBase
1, // SlotCount
0 // Reserved
};
STATIC CONST PLATFORM_SLOT_TABLE mSlotTableConfig2 = {
SLOT_TABLE_SIGNATURE, // Signature 'PSLT'
1, // Version
0xBB0, // GpioConfigBase
0x4B0, // SlotConfigBase
1, // SlotCount
0 // Reserved
};
/**
UBA debug print wrapper.
Locates the UBA debug print protocol and uses it to print the debug message.
@param[in] ErrorLevel Debug error level.
@param[in] Format Format string.
@param[in] ... Variable arguments for format string.
@return Status of the debug print operation.
**/
UINTN
UbaDebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
)
{
VA_LIST Marker;
UBA_DEBUG_PROTOCOL *Protocol;
UINTN Result;
Protocol = mDebugPrintProtocol;
Result = 0;
if (Protocol != NULL) {
//
// Read CMOS status register to check debug state
//
IoWrite8 (0x70, (IoRead8 (0x70) & 0x80) | 0x4B);
UINT8 DebugLevel = IoRead8 (0x71);
if (DebugLevel > 3) {
//
// Read debug enable from platform scratchpad (F000 segment)
//
if (DebugLevel == 0) {
DebugLevel = (*(volatile UINT8 *)(UINTN)0xFDAF0490 & 2) | 1;
}
}
if ((DebugLevel - 1) <= 0xFD) {
//
// Determine the actual debug print level based on CMOS
//
UINTN PrintErrorLevel = 0x80000086; // DEBUG_INFO | DEBUG_LOAD
if (DebugLevel == 1) {
PrintErrorLevel = 0x80000004; // DEBUG_ERROR
}
if ((PrintErrorLevel & ErrorLevel) != 0) {
VA_START (Marker, Format);
Result = Protocol->DebugPrint (ErrorLevel, Format, &Marker);
VA_END (Marker);
}
}
}
return Result;
}
/**
Debug assertion handler.
Invokes the UBA debug print protocol to report assertion failures.
@param[in] FileName Source file name of the assertion.
@param[in] LineNumber Line number of the assertion.
@param[in] Description Assertion description string.
**/
VOID
EFIAPI
AssertHandler (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
)
{
if (mDebugPrintProtocol != NULL) {
mDebugPrintProtocol->DebugPrint ((UINTN)FileName, LineNumber, (UINTN)Description);
}
}
/**
Initializes the UBA debug print protocol.
The protocol is located via the UEFI boot services and cached for
subsequent use by the debug print and assertion functions.
**/
STATIC
VOID
InitializeDebugProtocol (
VOID
)
{
EFI_STATUS Status;
if (mDebugPrintProtocol != NULL) {
return;
}
//
// Allocate pool for protocol lookup key
//
UINTN PoolSize = (*(UINTN (EFIAPI **)(UINTN))(gBootServices + 24))(31);
(*(VOID (EFIAPI **)(UINTN))(gBootServices + 32))(PoolSize);
if (PoolSize <= 16) {
Status = (*(EFI_STATUS (EFIAPI **)(VOID *, VOID *, VOID **))(gBootServices + 320))(
&gUbaDebugProtocolGuid,
NULL,
&mDebugPrintProtocol
);
if (EFI_ERROR (Status)) {
mDebugPrintProtocol = NULL;
}
} else {
mDebugPrintProtocol = NULL;
}
}
/**
Reads a 64-bit value from the specified address (unaligned-safe read).
@param[in] Buffer Pointer to the buffer to read from.
@return The 64-bit value at the specified address.
**/
UINT64
ReadUnaligned64 (
IN CONST VOID *Buffer
)
{
ASSERT (Buffer != NULL);
return *(UINT64 *)Buffer;
}
/**
Checks if a HOB entry matches the platform-specific HOB GUID.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] HobEntry Pointer to a HOB entry header.
@retval TRUE The HOB entry GUID matches the platform GUID.
@retval FALSE The HOB entry GUID does not match.
**/
BOOLEAN
IsPlatformSlotHob (
IN EFI_HANDLE ImageHandle,
IN VOID *HobEntry
)
{
GUID *HobGuid;
GUID PlatformHobGuid = LIGHTNING_RIDGE_EX_EC_B4_PLATFORM_HOB_GUID;
HobGuid = (GUID *)HobEntry;
return (CompareMem (&HobGuid->Data1, &PlatformHobGuid.Data1, sizeof (UINT64)) == 0 &&
CompareMem (&HobGuid->Data4, &PlatformHobGuid.Data4, sizeof (UINT64)) == 0);
}
/**
Retrieves the HOB list pointer from the system table.
Iterates through the HOB entries in the system table's HOB list to find
the gEfiHobListGuid entry and returns a pointer to the HOB list.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@return Pointer to the HOB list, or NULL if not found.
**/
VOID *
GetHobListInternal (
IN EFI_HANDLE ImageHandle
)
{
UINTN HobCount;
UINTN Index;
if (mHobList != NULL) {
return mHobList;
}
HobCount = gSystemTable->HobList.Raw != NULL ? *((UINTN *)gSystemTable->HobList.Raw) : 0;
mHobList = NULL;
if (gSystemTable->HobList.Raw != NULL) {
for (Index = 0; Index < HobCount; Index++) {
if (IsPlatformSlotHob (ImageHandle, (VOID *)(*((UINTN *)gSystemTable->HobList.Raw) + Index * 24))) {
mHobList = (VOID *)(*((UINTN *)gSystemTable->HobList.Raw + 24 * Index + 16));
break;
}
}
}
//
// If HOB list not found, assert
//
if (mHobList == NULL) {
DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", EFI_INVALID_PARAMETER));
ASSERT (FALSE);
}
ASSERT (mHobList != NULL);
return mHobList;
}
/**
Entry point for SlotDataUpdateDxeLightningRidgeEXECB4 driver.
This function performs the following:
1. Saves ImageHandle and SystemTable to global variables
2. Validates all required system table pointers
3. Initializes the HOB list
4. Prints a debug trace indicating the driver has loaded
5. Locates the slot configuration protocol
6. Installs platform-specific slot configuration protocol interfaces
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point executed successfully.
@retval EFI_INVALID_PARAMETER A required protocol could not be located.
@retval EFI_UNSUPPORTED The platform is not supported.
**/
EFI_STATUS
EFIAPI
SlotDataUpdateDxeEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
VOID *SlotProtocol;
//
// Save and validate ImageHandle
//
gImageHandle = ImageHandle;
ASSERT (ImageHandle != NULL);
//
// Save and validate SystemTable
//
gSystemTable = SystemTable;
ASSERT (SystemTable != NULL);
//
// Save and validate BootServices
//
gBootServices = SystemTable->BootServices;
ASSERT (gBootServices != NULL);
//
// Save and validate RuntimeServices
//
gRuntimeServices = SystemTable->RuntimeServices;
ASSERT (gRuntimeServices != NULL);
//
// Initialize debug print protocol
//
InitializeDebugProtocol ();
//
// Retrieve the HOB list (populates gHobList global)
//
GetHobListInternal (ImageHandle);
//
// Print driver load trace message
//
UbaDebugPrint (
0x80000000,
"UBA:SlotDataUpdate-TypeLightningRidgeEXECB3\n"
);
//
// Locate the slot configuration protocol to install onto
//
Status = gBootServices->LocateProtocol (
&gLightningRidgeExEcB4SlotProtocolGuid,
NULL,
&SlotProtocol
);
if (!EFI_ERROR (Status)) {
//
// Install first slot configuration (32 bytes of slot table data)
// Protocol GUID: LIGHTNING_RIDGE_EX_EC_B4_SLOT_TABLE_PROTOCOL_GUID
// Interface: mSlotTableConfig1
//
Status = ((EFI_SLOT_PROTOCOL *)SlotProtocol)->InstallProtocol (
SlotProtocol,
&gLightningRidgeExEcB4SlotTableProtocolGuid,
(VOID *)&mSlotTableConfig1,
32
);
}
return Status;
}
/**
Standard UEFI driver entry point.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The driver loaded successfully.
@retval other An error occurred during driver initialization.
**/
EFI_STATUS
EFIAPI
_ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return SlotDataUpdateDxeEntryPoint (ImageHandle, SystemTable);
}