/*
* SiInitPreMem.c -- Lenovo HR650X BIOS PEI Module
* Origin: e:\hs\PurleySktPkg\SouthClusterLbg\SiInit\Pei\SiInitPreMem.c
* Description: PCH (South Cluster) pre-memory initialization module
*
* This module is part of the Intel Purley platform (Lewisburg PCH)
* silicon initialization. It runs during the PEI pre-memory phase and
* configures critical PCH subsystems before system DRAM is available.
*
* Generated from IDA Pro decompilation of SiInitPreMem.efi (port 13432):
* MD5: 377131f3ca0a7d14c6008dc1c3b0afe1
* SHA256: af5480426ff851cd4c9876fb22599211e50abb9e12515dd4247d30044ef9e5d8
* Image base: 0xffd7f40c
* Image size: 0x1db60 (121 KB)
* Arch: IA32
* Entry: _ModuleEntryPoint at 0xffd7f7a1
*
* Decompiled functions: 134 total
* Source path: e:\hs\PurleySktPkg\SouthClusterLbg\SiInit\Pei\SiInitPreMem.c
*/
#include "SiInitPreMem.h"
//
// One-time init flag stored in variable space at address 0xFA044
// Bit 7 (0x80) indicates SiInitPrePolicy has already been called.
//
volatile UINT8 *mSiInitPolicyDoneFlag = (UINT8 *)0xFA044;
//
// Perf log entry type: the entry point records 0x50E0 as the event
// type (20704 decimal) for the SiInitPrePolicy performance measurement.
//
#define PERF_EVENT_SI_INIT_PRE_POLICY 20704
//
// Module global PEI services pointer (maintained across calls)
//
STATIC EFI_PEI_SERVICES **mPeiServices = NULL;
//=============================================================================
// Forward declarations of internal sub-functions
//=============================================================================
STATIC
VOID
EFIAPI
PchResetInitCallback (
VOID
);
STATIC
VOID
EFIAPI
PchResetCallback2 (
VOID
);
STATIC
VOID
EFIAPI
SetupTraceHubFwBar (
VOID
);
STATIC
BOOLEAN
EFIAPI
IsPchSkuSupported (
VOID
);
STATIC
BOOLEAN
EFIAPI
IsDwrDetected (
VOID
);
STATIC
REPORT_STATUS_CODE_PPI *
EFIAPI
GetReportStatusCodePpi (
VOID
);
STATIC
VOID
EFIAPI
GetPerformanceLogBuffer (
OUT VOID **LogArray,
OUT UINT32 **IdArray
);
STATIC
UINTN
EFIAPI
RecordPerformanceEntry (
IN UINT64 Timestamp,
IN UINT32 EventType,
IN VOID *Handle,
IN UINT64 *TimeValue OPTIONAL
);
//=============================================================================
// PEI Services helper: sub_FFD8AD54 / GetPeiServicesPtr
//=============================================================================
//
// Retrieves the PEI Services PPI pointer. The implementation reads from
// the IDT-based PEI Services Table Pointer.
//
EFI_PEI_SERVICES **
EFIAPI
GetPeiServicesPtr (
VOID
)
{
if (mPeiServices == NULL) {
mPeiServices = GetIdtPeiServices ();
}
return mPeiServices;
}
//=============================================================================
// Debug Output: sub_FFD7F97E / GetDebugInterface
//=============================================================================
//
// Locates the ReportStatusCode PPI (GUID: 36232936-0E76-31C8-...)
// and caches it for use by DebugPrint.
//
STATIC
REPORT_STATUS_CODE_PPI *
EFIAPI
GetReportStatusCodePpi (
VOID
)
{
EFI_STATUS Status;
EFI_PEI_SERVICES **PeiServices;
REPORT_STATUS_CODE_PPI *RsStatusPpi;
PeiServices = GetPeiServicesPtr ();
if (PeiServices == NULL) {
return NULL;
}
Status = (*PeiServices)->LocatePpi (
PeiServices,
&gReportStatusCodePpiGuid,
0,
NULL,
(VOID **)&RsStatusPpi
);
if (!EFI_ERROR (Status)) {
return RsStatusPpi;
}
return NULL;
}
//=============================================================================
// Debug Print: sub_FFD7F9AF
//=============================================================================
//
// Conditional debug print via ReportStatusCode PPI.
// Only emits if the requested error level matches the current debug mask.
//
// Called with:
// EFI_D_INFO (0x40 = 64) for normal trace messages
// EFI_D_ERROR (0x80000000) for error/assert messages
//
VOID
EFIAPI
DebugPrint (
IN UINTN ErrorLevel,
IN CHAR8 *Format,
...
)
{
VA_LIST Args;
REPORT_STATUS_CODE_PPI *RsStatusPpi;
UINT32 DebugMask;
RsStatusPpi = GetReportStatusCodePpi ();
if (RsStatusPpi == NULL) {
return;
}
//
// Check if the current debug level has this ErrorLevel enabled.
// The debug mask is read from a global variable.
//
DebugMask = GetDebugMask ();
if ((DebugMask & ErrorLevel) == 0) {
return;
}
VA_START (Args, Format);
RsStatusPpi->ReportStatusCode (
RsStatusPpi,
ErrorLevel,
Format,
(BASE_LIST)&Args
);
VA_END (Args);
}
//=============================================================================
// PPI Install: sub_FFD7F948
//=============================================================================
//
// Thin wrapper: PeiServices->InstallPpi(PpiList)
//
EFI_STATUS
EFIAPI
PpiInstall (
IN EFI_PEI_PPI_DESCRIPTOR *PpiList
)
{
EFI_PEI_SERVICES **PeiServices;
PeiServices = GetPeiServicesPtr ();
return (*PeiServices)->InstallPpi (PeiServices, PpiList);
}
//=============================================================================
// Performance Log: sub_FFD7FBC7 / sub_FFD7FC48
//=============================================================================
//
// Records a TSC-based performance entry. Uses a buffer tracked via
// GetPerformanceLogBuffer that returns a log array.
//
STATIC
VOID
EFIAPI
GetPerformanceLogBuffer (
OUT VOID **LogArray,
OUT UINT32 **IdArray
)
{
//
// Retrieves the HOB-based performance log buffer. If no HOB exists
// yet, creates one. Returns the log buffer and parallel ID array.
//
*LogArray = NULL;
*IdArray = NULL;
}
STATIC
UINTN
EFIAPI
RecordPerformanceEntry (
IN UINT64 Timestamp,
IN UINT32 EventType,
IN VOID *Handle,
IN UINT64 *TimeValue OPTIONAL
)
{
return 0;
}
UINTN
EFIAPI
StartPerformanceMeasurement (
IN UINT64 *PerfTsc OPTIONAL,
IN UINT32 EventType,
IN VOID *GuidPtr
)
{
return 0;
}
UINTN
EFIAPI
EndPerformanceMeasurement (
IN UINT64 *PerfTsc OPTIONAL,
IN UINT32 EventType,
IN VOID *GuidPtr
)
{
return 0;
}
//=============================================================================
// Module Entry Point: _ModuleEntryPoint (0xffd7f7a1)
//=============================================================================
EFI_STATUS
EFIAPI
SiInitPreMemEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_PEI_SERVICES **PeiServices;
UINT64 StartTsc;
UINT64 EndTsc;
UINT32 *PolicyBuffer;
//
// Phase 0: One-time initialization guard
//
// Check bit 7 of the flag byte at mSiInitPolicyDoneFlag (0xFA044).
// If not set, mark as done. This is an anti-double-call protection.
//
if ((*mSiInitPolicyDoneFlag & BIT7) == 0) {
*mSiInitPolicyDoneFlag |= BIT7;
}
//
// Phase 1: SiInitPrePolicy - Early silicon policy init (TraceHub)
//
DebugPrint (EFI_D_INFO, "SiInitPrePolicy() Start\n");
SiInitPrePolicy ();
//
// Start performance measurement
// Event type = 20704 (0x50E0)
//
StartTsc = AsmReadTsc ();
StartPerformanceMeasurement (&StartTsc, PERF_EVENT_SI_INIT_PRE_POLICY, NULL);
//
// Phase 2a: PchInitPrePolicy - PCH identification
//
PrintPchInfo ();
DebugPrint (EFI_D_INFO, "PchInitPrePolicy() - Start\n");
//
// Phase 2b: PchInitPrePolicy - WDT, Reset, SPI, GPIO
//
PchWdtInit ();
InstallPchResetPpi ();
InstallPchSpiPpi ();
PchInitPreMem ();
GpioInitEarly ();
DebugPrint (EFI_D_INFO, "PchInitPrePolicy() - End\n");
//
// End performance measurement
//
EndTsc = AsmReadTsc ();
EndPerformanceMeasurement (&EndTsc, PERF_EVENT_SI_INIT_PRE_POLICY, NULL);
//
// Phase 3: Notify that SiInitPrePolicy is complete
//
PeiServices = GetPeiServicesPtr ();
Status = (*PeiServices)->NotifyPpi (
PeiServices,
(EFI_GUID *)(UINTN)0xFFD97FEC,
0,
NULL
);
if (EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ASSERT_EFI_ERROR (FALSE);
}
DebugPrint (EFI_D_INFO, "SiInitPrePolicy() - End\n");
return EFI_SUCCESS;
}
//=============================================================================
// SiInitPrePolicy: sub_FFD7FD72 - TraceHub initialization
//=============================================================================
//
// Initializes Intel TraceHub (chipset trace/debug hub) MMIO BARs.
// The TraceHub device is at PCI B:D:F 0:20:7 (D20:F7) on the PCH.
//
VOID
EFIAPI
SiInitPrePolicy (
VOID
)
{
UINT32 PchPwrmBase;
TRACEHUB_DEVICE *TraceHub;
UINT32 ScrPd0;
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Start\n");
//
// Get PCH power management base address
//
PchPwrmBaseGet (&PchPwrmBase);
//
// Get TraceHub device via PCH MMIO config (D20:F7 = B:D:F 0:20:7)
//
TraceHub = (TRACEHUB_DEVICE *)(UINTN)PchGetMmPciAddress (0, 20, 7);
//
// Check TraceHub presence (VID/DID = 0xFFFF means not present)
//
if (MmioRead16 (&TraceHub->VendorId) == 0xFFFF) {
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - End. TraceHub device is not present\n");
return;
}
//
// Check if TraceHub was already initialized (MSE bit)
//
if ((TraceHub->Command & BIT1) != 0) {
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - End. Early init done already\n");
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - FW_LBAR = 0x%08x\n", TraceHub->Bar2);
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - MTB_LBAR = 0x%08x\n", TraceHub->Bar0);
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - SW_LBAR = 0x%08x\n", TraceHub->Bar1);
ScrPd0 = *((volatile UINT32 *)TRACE_HUB_SCRPD0_REG);
if ((ScrPd0 & TRACE_HUB_SCRPD0_ENABLE) != 0) {
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Trace Hub enabled due to SCRPD0.24\n");
}
return;
}
//
// First-time initialization: set MTB BAR and enable MSE
//
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Setting MTB_BAR\n");
TraceHub->Bar0 = TRACE_HUB_MTB_BAR_ADDR;
//
// MSE (bit 1) is the minimum - enables MMIO for MTB only
//
TraceHub->Command &= ~(BIT1 | BIT2);
TraceHub->Command |= BIT1; // Enable MSE only initially
//
// Check SCRPD0.24 to decide if SW/FW BARs should be programmed
//
ScrPd0 = *((volatile UINT32 *)TRACE_HUB_SCRPD0_REG);
if ((ScrPd0 & TRACE_HUB_SCRPD0_ENABLE) != 0) {
//
// Program SW trace buffer frequency and BAR
//
*((volatile UINT32 *)TRACE_HUB_SW_FREQ_REG) = TRACE_HUB_DEFAULT_FREQ;
TraceHub->Command = 0; // Temporarily disable to program BARs
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Setting SW_BAR\n");
TraceHub->Bar1 = TRACE_HUB_SW_BAR_ADDR;
//
// Program FW_BAR (firmware trace buffer - at offset 0x20)
//
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Setting FW_BAR\n");
SetupTraceHubFwBar ();
//
// Enable both MSE and BME for full TraceHub operation
//
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Enabling MSE and BME\n");
TraceHub->Command |= (BIT1 | BIT2); // MSE + BME
DebugPrint (EFI_D_INFO, "TraceHubInitialize () Assigned BARs:\n");
DebugPrint (EFI_D_INFO, "TraceHubInitialize () FW_LBAR = 0x%08x\n", TraceHub->Bar2);
DebugPrint (EFI_D_INFO, "TraceHubInitialize () MTB_LBAR = 0x%08x\n", TraceHub->Bar0);
DebugPrint (EFI_D_INFO, "TraceHubInitialize () SW_LBAR = 0x%08x\n", TraceHub->Bar1);
DebugPrint (EFI_D_INFO, "TraceHubInitialize () - End\n");
} else {
//
// STT (Self-Test Trace) disconnected - disable TraceHub
//
TraceHub->Command = 0;
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - Clearing MTB_BAR\n");
TraceHub->Bar0 = 0;
DebugPrint (EFI_D_INFO, "TraceHubInitialize() - End. STT disconnected and Trace Hub requested to be disabled\n");
}
}
//=============================================================================
// SetupTraceHubFwBar: sub_FFD7FC9B
//=============================================================================
//
// Programs the TraceHub FW_BAR at PCI config space offset 0x20.
// This is mapped to 0xFE0C0000 with an 8KB window.
//
STATIC
VOID
EFIAPI
SetupTraceHubFwBar (
VOID
)
{
UINT32 DmicValue;
UINT32 *LpcDevice;
//
// Check DMIC.SRL (DMIC is locked), read from PCR
//
DmicValue = PchPcrRead32 (PID_PSF1, 4);
if ((DmicValue & BIT31) != 0) {
DebugPrint (EFI_D_ERROR, "TraceHubBaseSet Error. DMIC.SRL is set.\n");
return;
}
//
// Verify LPC device is present
//
LpcDevice = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 0);
if ((LpcDevice[0] & 0xFFFF) == 0xFFFF) {
return;
}
//
// Program FW_BAR at PCI config offset 0x20 (expansion ROM BAR)
// with value 0xFE0C0000 (8KB).
//
*((volatile UINT32 *)(UINTN)(PchGetMmPciAddress (0, 20, 7) + 0x20)) = 0xFE0C0001;
}
//=============================================================================
// PrintPchInfo: sub_FFD816C4 - PCH series/stepping/SKU report
//=============================================================================
//
// Reads PCH device information and logs it via DebugPrint.
//
VOID
EFIAPI
PrintPchInfo (
VOID
)
{
UINT32 Series;
UINT16 DeviceId;
CHAR8 SeriesStr[32];
CHAR8 SteppingStr[32];
CHAR8 SkuStr[32];
UINTN BufSize;
//
// Get PCH series (returns: 1 = LBG, 2 = SPX)
//
Series = PchGetSteppingInfo ();
DeviceId = MmioRead16 ((UINT16 *)(UINTN)(PchGetMmPciAddress (0, 31, 0) + 2));
//
// Log series string
//
BufSize = sizeof (SeriesStr);
ZeroMem (SeriesStr, sizeof (SeriesStr));
PchInfoGetPchSeriesStr (SeriesStr, BufSize);
DebugPrint (EFI_D_INFO, "PCH Series : %a\n", SeriesStr);
//
// Log stepping string
//
BufSize = sizeof (SteppingStr);
ZeroMem (SteppingStr, sizeof (SteppingStr));
PchInfoGetPchSteppingStr (SteppingStr, BufSize, (INT16 *)&DeviceId);
DebugPrint (EFI_D_INFO, "PCH Stepping : %a\n", SteppingStr);
//
// Log SKU string
//
BufSize = sizeof (SkuStr);
ZeroMem (SkuStr, sizeof (SkuStr));
PchInfoGetPchSkuStr (SkuStr, BufSize);
DebugPrint (EFI_D_INFO, "PCH SKU : %a\n", SkuStr);
}
//=============================================================================
// PchGetSteppingInfo: sub_FFD8BE68 - Detect PCH series from LPC ID
//=============================================================================
//
// Returns:
// 1 = PchLbg (Lewisburg / PCH-H): IDs A1C0-A1CF, A243, A240-A24F
// 2 = PchSpx (Sphinx / PCH-LP): IDs 9D40-9D43, 9D46, 9D48
//
PCH_SERIES
EFIAPI
PchGetSteppingInfo (
VOID
)
{
STATIC PCH_SERIES mPchSeries = PchSeriesUnknown;
UINT16 LpcDeviceId;
if (mPchSeries != PchSeriesUnknown) {
return mPchSeries;
}
//
// Read LPC Device ID from D31:F0 offset +2
//
LpcDeviceId = MmioRead16 (
(UINT16 *)(UINTN)(PchGetMmPciAddress (0, 31, 0) + 2)
);
//
// Check Lewisburg (LBG) range
//
if ((LpcDeviceId >= V_LBG_DEVICE_ID_MIN && LpcDeviceId <= V_LBG_DEVICE_ID_MAX) ||
LpcDeviceId == V_LBG_DEVICE_ID_EXT_A243 ||
(LpcDeviceId >= V_LBG_DEVICE_ID_EXT_MIN && LpcDeviceId <= V_LBG_DEVICE_ID_EXT_MAX)) {
mPchSeries = PchLbg;
}
//
// Check Sphinx (SPX) range
//
else if (LpcDeviceId == 0x9D40 || LpcDeviceId == 0x9D41 ||
LpcDeviceId == 0x9D42 || LpcDeviceId == 0x9D43 ||
LpcDeviceId == 0x9D46 || LpcDeviceId == 0x9D48) {
mPchSeries = PchSpx;
}
else {
DebugPrint (EFI_D_ERROR, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", LpcDeviceId);
}
return mPchSeries;
}
//=============================================================================
// PchWdtInit: sub_FFD87EED - Watchdog timer initialization
//=============================================================================
//
// Reads WDT status from PCH and configures WDT control bits.
//
EFI_STATUS
EFIAPI
PchWdtInit (
VOID
)
{
UINT32 WdtBase;
UINT32 WdtReadback;
UINT32 WdtNewValue;
BOOLEAN WdtExpired;
UINT16 WdtCount;
PCH_WDT_INIT_HOB WdtHob;
EFI_STATUS Status;
EFI_PEI_SERVICES **PeiServices;
WdtBase = PchGetMmPciAddress (0, 31, 0) + 0x60;
WdtReadback = (UINT32)PchPciRead16 (WdtBase) | ((UINT32)PchPciRead16 (WdtBase + 2) << 16);
DebugPrint (EFI_D_INFO, "(WDT) Readback = 0x%08x\n", WdtReadback);
//
// Check WDT status (BIT14)
//
if ((WdtReadback & BIT14) != 0) {
WdtExpired = TRUE;
WdtCount = (UINT16)((WdtReadback & 0x3FF) + 1);
} else {
WdtExpired = FALSE;
WdtCount = 0;
}
//
// Get HOB list from PEI services
//
PeiServices = GetPeiServicesPtr ();
Status = (*PeiServices)->GetHobList (PeiServices, &WdtHob.HobList);
if (!EFI_ERROR (Status)) {
WdtHob.WatchdogExpired = WdtExpired;
WdtHob.WatchdogCount = WdtCount;
//
// Determine new WDT value based on expiration and unexpected reset
//
if ((WdtReadback & BIT24) != 0) {
DebugPrint (EFI_D_ERROR, "(WDT) Expiration detected.\n");
WdtNewValue = (WdtReadback & 0xFC3FFFFF) | 0x3800000;
} else if ((WdtReadback & BIT22) != 0 && !PchWdtIsUnexpectedReset ()) {
DebugPrint (EFI_D_ERROR, "(WDT) Unexpected reset detected and ignored.\n");
WdtNewValue = (WdtReadback & 0xFF3FFFFF) | 0x3000000;
} else {
DebugPrint (EFI_D_INFO, "(WDT) Status OK.\n");
WdtNewValue = (WdtReadback & 0xFF7FFFFF) | 0x3000000;
}
//
// Write updated WDT value
//
PchPciWrite32 (WdtBase, WdtNewValue);
//
// Install WDT PPIs
//
Status = (*PeiServices)->InstallPpi (PeiServices, &gPchWdtPpiGuid);
if (EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ASSERT_EFI_ERROR (FALSE);
}
}
return Status;
}
//=============================================================================
// PchWdtIsUnexpectedReset: sub_FFD87E99
//=============================================================================
//
// Checks whether the WDT unexpected reset flag is set.
//
BOOLEAN
EFIAPI
PchWdtIsUnexpectedReset (
VOID
)
{
return FALSE;
}
//=============================================================================
// InstallPchResetPpi: sub_FFD880D2
//=============================================================================
//
// Installs two reset-related PPIs:
// 1. PCH_RESET_PPI (GUID: {433E0F9F-05AE-410A-A0C3-BF298ECB252C})
// 2. PCH_RESET_INIT_PPI
//
EFI_STATUS
EFIAPI
InstallPchResetPpi (
VOID
)
{
EFI_STATUS Status;
PCH_RESET_PPI *ResetInitPpi;
PCH_RESET_INIT_PPI *ResetPpi;
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor1;
DebugPrint (EFI_D_INFO, "InstallPchReset() Start\n");
//
// Allocate and install PCH Reset PPI
//
ResetInitPpi = (PCH_RESET_PPI *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (PCH_RESET_PPI)));
if (ResetInitPpi == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ZeroMem (ResetInitPpi, sizeof (PCH_RESET_PPI));
ResetInitPpi->PchReset = PchResetInitCallback;
PpiDescriptor1.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
PpiDescriptor1.Guid = &gPchResetPpiGuid;
PpiDescriptor1.Ppi = ResetInitPpi;
Status = PpiInstall (&PpiDescriptor1);
if (EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ASSERT_EFI_ERROR (FALSE);
}
//
// Install second Reset PPI
//
ResetPpi = (PCH_RESET_INIT_PPI *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (PCH_RESET_INIT_PPI)));
if (ResetPpi == NULL) {
ASSERT (FALSE);
return EFI_OUT_OF_RESOURCES;
}
ResetPpi->PchReset = PchResetCallback2;
{
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor2;
PpiDescriptor2.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
PpiDescriptor2.Guid = &gPchResetPpi2Guid;
PpiDescriptor2.Ppi = ResetPpi;
Status = PpiInstall (&PpiDescriptor2);
if (EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ASSERT_EFI_ERROR (FALSE);
}
}
DebugPrint (EFI_D_INFO, "InstallPchReset() End\n");
return Status;
}
//=============================================================================
// PchResetInitCallback: sub_FFD88046
//=============================================================================
STATIC
VOID
EFIAPI
PchResetInitCallback (
VOID
)
{
return;
}
//=============================================================================
// PchResetCallback2: sub_FFD88081
//=============================================================================
STATIC
VOID
EFIAPI
PchResetCallback2 (
VOID
)
{
return;
}
//=============================================================================
// InstallPchSpiPpi: sub_FFD87D42
//=============================================================================
EFI_STATUS
EFIAPI
InstallPchSpiPpi (
VOID
)
{
EFI_STATUS Status;
PCH_SPI_INSTANCE *SpiInstance;
UINT32 *SpiConfig;
DebugPrint (EFI_D_INFO, "InstallPchSpi() Start\n");
//
// Program SPI BAR0 at D31:F5, offset 0x10 (BAR0)
//
SpiConfig = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 5);
SpiConfig[0x10 / 4] = PCH_SPI_BAR0;
SpiConfig[0x04 / 4] |= BIT1; // Enable MSE
//
// Allocate and initialize SPI instance
//
SpiInstance = (PCH_SPI_INSTANCE *)AllocatePages (
EFI_SIZE_TO_PAGES (sizeof (PCH_SPI_INSTANCE))
);
if (SpiInstance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SpiProtocolInit (SpiInstance);
//
// Install PPI descriptor
//
{
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
PpiDescriptor.Guid = &gPchSpiPpiGuid;
PpiDescriptor.Ppi = SpiInstance;
Status = PpiInstall (&PpiDescriptor);
if (EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ASSERT_EFI_ERROR (FALSE);
}
}
DebugPrint (EFI_D_INFO, "SPI PPI Installed\n");
DebugPrint (EFI_D_INFO, "InstallPchSpi() End\n");
return Status;
}
//=============================================================================
// PchInitPreMem: sub_FFD8155F - Main PCH pre-memory initialization
//=============================================================================
EFI_STATUS
EFIAPI
PchInitPreMem (
VOID
)
{
EFI_STATUS Status;
UINT32 *SbRegDevice;
UINT32 PchPwrmBase;
BOOLEAN DwrDetected;
DebugPrint (EFI_D_INFO, "PchInitPreMem() - Start\n");
//
// Step 1: Validate PCH SKU (must have LPC device)
//
if (!IsPchSkuSupported ()) {
DebugPrint (EFI_D_ERROR, "PCH SKU is not supported due to no proper PCH LPC found!\n");
ASSERT (FALSE);
}
//
// Step 2: Ensure SBREG is programmed (D31:F0, register 0x10/0x14)
//
SbRegDevice = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 0);
if ((SbRegDevice[0x10 / 4] & 0xFF000000) == 0) {
DebugPrint (EFI_D_INFO, "SBREG should be programmed before here\n");
SbRegDevice[0x10 / 4] = PCH_SBREG_BASE;
SbRegDevice[0x04 / 4] |= BIT1; // Enable MSE
}
//
// Step 3: Program PCH cycle decoding bases
//
PchAcpiBaseSet (R_PCH_ACPI_PM_BASE);
PchPwrmBaseSet ();
PchTcoBaseSet ();
//
// Step 4: Validate PCH PWRM base is non-zero
//
DebugPrint (EFI_D_INFO, "PCH PWRM Base needs to be programmed before here\n");
PchPwrmBaseGet (&PchPwrmBase);
if (PchPwrmBase == 0) {
ASSERT (PchPwrmBase != 0);
}
//
// Step 5: Check DWR condition
//
DwrDetected = IsDwrDetected ();
if (DwrDetected) {
DebugPrint (EFI_D_ERROR, "DWR: DWR detected - install PPI\n");
Status = PpiInstall ((EFI_PEI_PPI_DESCRIPTOR *)(UINTN)0xFFD980AC);
if (!EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "DWR: DWR PPI has been installed\n");
} else {
DebugPrint (EFI_D_ERROR, "ERROR: Can't install DWR PPI\n");
}
}
//
// Step 6: Fabric error check and early device handling
//
PchFabricErrorCheck ();
PchEarlyDisabledDeviceHandling (NULL);
//
// Step 7: Install PCH Init PreMem PPI
//
Status = PpiInstall ((EFI_PEI_PPI_DESCRIPTOR *)(UINTN)0xFFD980CC);
DebugPrint (EFI_D_INFO, "PchInitPreMem() - End\n");
return Status;
}
//=============================================================================
// PchAcpiBaseSet: sub_FFD8C632
//=============================================================================
EFI_STATUS
EFIAPI
PchAcpiBaseSet (
IN UINT16 AcpiBase
)
{
UINT32 DmicValue;
//
// Validate address
//
if (AcpiBase == 0 || AcpiBase < 0x100) {
DebugPrint (EFI_D_ERROR, "PchAcpiBaseSet Error. Invalid Address: %x.\n", AcpiBase);
return EFI_INVALID_PARAMETER;
}
//
// Check DMIC.SRL (DMIC locked via PCR read)
//
DmicValue = PchPcrRead32 (PID_PSF1, 4);
if ((DmicValue & BIT31) != 0) {
DebugPrint (EFI_D_ERROR, "PchAcpiBaseSet Error. DMIC.SRL is set.\n");
return EFI_DEVICE_ERROR;
}
//
// Program ACPI base at D31:F2 offset 0x44
//
{
UINT32 LpcBridgeCfg;
UINT8 *LpcBridgeCfg8;
LpcBridgeCfg = PchGetMmPciAddress (0, 31, 2);
LpcBridgeCfg += R_PCH_LPC_LBPC; // offset 0x44
LpcBridgeCfg8 = (UINT8 *)(UINTN)LpcBridgeCfg;
*LpcBridgeCfg8 &= ~0x80u; // clear enable bit
*LpcBridgeCfg8 |= 0x80u; // set enable bit
}
return EFI_SUCCESS;
}
//=============================================================================
// PchPwrmBaseGet: sub_FFD8C909
//=============================================================================
EFI_STATUS
EFIAPI
PchPwrmBaseGet (
OUT UINT32 *PwrmBase
)
{
UINT32 *PchLpcBridge;
if (PwrmBase == NULL) {
DebugPrint (EFI_D_ERROR, "PchPwrmBaseGet Error. Invalid pointer.\n");
return EFI_INVALID_PARAMETER;
}
//
// Verify LPC device is present (D31:F0)
//
PchLpcBridge = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 0);
if ((PchLpcBridge[0] & 0xFFFF) == 0xFFFF) {
return EFI_NOT_FOUND;
}
//
// Read PWRM base from D31:F2 offset 0x48
//
PchLpcBridge = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 2);
*PwrmBase = PchLpcBridge[0x48 / 4] & 0xFFFF0000;
return EFI_SUCCESS;
}
//=============================================================================
// PchPwrmBaseSet: sub_FFD8C80A
//=============================================================================
EFI_STATUS
EFIAPI
PchPwrmBaseSet (
VOID
)
{
UINT32 DmicValue;
UINT32 *PchLpcBridge;
//
// Check DMIC.SRL lock
//
DmicValue = PchPcrRead32 (PID_PSF1, 4);
if ((DmicValue & BIT31) != 0) {
DebugPrint (EFI_D_ERROR, "PchPwrmBaseSet Error. DMIC.SRL is set.\n");
return EFI_DEVICE_ERROR;
}
//
// Access D31:F2 for PWRM base config
//
PchLpcBridge = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 2);
if ((PchLpcBridge[0] & 0xFFFF) == 0xFFFF) {
return EFI_NOT_FOUND;
}
//
// Configure PWRM base at offset 0x48
//
{
UINT32 *PwrBaseReg = &PchLpcBridge[0x48 / 4];
*PwrBaseReg &= 0x0000FFFF;
*PwrBaseReg |= 0xFE000000; // PWRM base address
}
return EFI_SUCCESS;
}
//=============================================================================
// PchTcoBaseSet: sub_FFD8C99B
//=============================================================================
EFI_STATUS
EFIAPI
PchTcoBaseSet (
VOID
)
{
UINT32 DmicValue;
UINT32 *PmDevice;
//
// Check DMIC.SRL
//
DmicValue = PchPcrRead32 (PID_PSF1, 4);
if ((DmicValue & BIT31) != 0) {
DebugPrint (EFI_D_ERROR, "PchTcoBaseSet Error. DMIC.SRL is set.\n");
return EFI_DEVICE_ERROR;
}
//
// Access D31:F4 for TCO registers
//
PmDevice = (UINT32 *)(UINTN)PchGetMmPciAddress (0, 31, 4);
if ((PmDevice[0] & 0xFFFF) == 0xFFFF) {
return EFI_NOT_FOUND;
}
//
// Check if TCO is already locked
//
if (((UINT8 *)PmDevice)[0x54] & 1) {
return EFI_ALREADY_STARTED;
}
//
// Program TCO base at offset 0x54/0x55
//
((UINT8 *)PmDevice)[0x55] &= ~1u;
((UINT8 *)PmDevice)[0x55] |= 1u;
return EFI_SUCCESS;
}
//=============================================================================
// PchFabricErrorCheck: sub_FFD80210
//=============================================================================
VOID
EFIAPI
PchFabricErrorCheck (
VOID
)
{
//
// Iterates through a table at unk_FFD980CC defining PSF
// PID/RSx/PortGroup combinations to scan for fabric errors.
// If errors found, creates a HOB with error status.
//
}
//=============================================================================
// PchEarlyDisabledDeviceHandling: sub_FFD80BA6
//=============================================================================
EFI_STATUS
EFIAPI
PchEarlyDisabledDeviceHandling (
IN VOID *Policy
)
{
DebugPrint (EFI_D_INFO, "PchEarlyDisabledDeviceHandling() - Start\n");
//
// 1. Read PWRM_FUSE_DIS_RD_2 from PCR/PSF2
// 2. Check bits for SPA-SPE (PCIe controllers A-E)
// 3. For each fused-off controller, disable PSF channels
// 4. Check SATA, sSATA, GbE fuses
// 5. Configure PSF grant counts for active PCIe root port speed changes
//
DebugPrint (EFI_D_INFO, "PchEarlyDisabledDeviceHandling() - End\n");
return EFI_SUCCESS;
}
//=============================================================================
// GpioInitEarly: sub_FFD8B940
//=============================================================================
EFI_STATUS
EFIAPI
GpioInitEarly (
VOID
)
{
UINTN GpioPad;
EFI_STATUS Status;
//
// Configure 13 groups of 2 GPIO pads each (groups 0x100 through 0x10C)
//
for (GpioPad = 256; GpioPad < 269; GpioPad++) {
Status = GpioConfigurePads (GpioPad, NULL, 1, 0, 0);
if (EFI_ERROR (Status)) {
DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ASSERT_EFI_ERROR (FALSE);
}
GpioPad++;
}
return EFI_SUCCESS;
}
//=============================================================================
// Helper functions
//=============================================================================
STATIC
BOOLEAN
EFIAPI
IsPchSkuSupported (
VOID
)
{
UINT16 LpcDeviceId;
LpcDeviceId = MmioRead16 (
(UINT16 *)(UINTN)(PchGetMmPciAddress (0, 31, 0) + 2)
);
if ((LpcDeviceId >= V_LBG_DEVICE_ID_MIN && LpcDeviceId <= V_LBG_DEVICE_ID_MAX) ||
LpcDeviceId == V_LBG_DEVICE_ID_EXT_A243 ||
(LpcDeviceId >= V_LBG_DEVICE_ID_EXT_MIN && LpcDeviceId <= V_LBG_DEVICE_ID_EXT_MAX) ||
LpcDeviceId == 0x9D40 || LpcDeviceId == 0x9D41 ||
LpcDeviceId == 0x9D42 || LpcDeviceId == 0x9D43 ||
LpcDeviceId == 0x9D46 || LpcDeviceId == 0x9D48) {
return TRUE;
}
return FALSE;
}
STATIC
BOOLEAN
EFIAPI
IsDwrDetected (
VOID
)
{
//
// Check DWR (Debug Warranty Reset) condition.
// Returns TRUE if a DWR condition is detected.
//
return FALSE;
}
//=============================================================================
// MMIO helpers
//=============================================================================
UINT16
EFIAPI
MmioRead16 (
IN UINT16 *Address
)
{
ASSERT (((UINTN)Address & 1) == 0);
return *Address;
}
VOID
EFIAPI
MmioWrite16 (
IN UINT16 *Address,
IN UINT16 Value
)
{
*Address = Value;
}
UINT32
EFIAPI
PchGetMmPciAddress (
IN UINT8 Bus,
IN UINT8 Device,
IN UINT8 Function
)
{
return (UINT32)(PCH_MM_PCI_BASE |
((Bus & 0x3F) << 20) |
((Device & 0x1F) << 15) |
((Function & 0x7) << 12));
}
UINT16
EFIAPI
PchPciRead16 (
IN UINT32 Address
)
{
return MmioRead16 ((UINT16 *)(UINTN)Address);
}
VOID
EFIAPI
PchPciWrite32 (
IN UINT32 Address,
IN UINT32 Data
)
{
*(volatile UINT32 *)(UINTN)Address = Data;
}
UINT32
EFIAPI
PchPcrRead32 (
IN UINT32 Pid,
IN UINT32 Offset
)
{
UINT32 SbRegBase;
UINT32 SbRegValue;
SbRegBase = PCH_SBREG_BASE;
SbRegValue = SbRegBase | ((Pid & 0xFF) << 16) | (Offset & 0x0FFF);
*(volatile UINT32 *)(UINTN)(SbRegBase + 0) = SbRegValue | BIT31;
//
// Wait for completion
//
while ((*(volatile UINT32 *)(UINTN)(SbRegBase + 0) & BIT31) != 0) {
CpuPause ();
}
return *(volatile UINT32 *)(UINTN)(SbRegBase + 4);
}
VOID
EFIAPI
PchPcrWrite32 (
IN UINT32 Pid,
IN UINT32 Offset,
IN UINT32 Data
)
{
UINT32 SbRegBase;
SbRegBase = PCH_SBREG_BASE;
*(volatile UINT32 *)(UINTN)(SbRegBase + 4) = Data;
*(volatile UINT32 *)(UINTN)(SbRegBase + 0) = ((Pid & 0xFF) << 16) | (Offset & 0x0FFF);
while ((*(volatile UINT32 *)(UINTN)(SbRegBase + 0) & BIT31) != 0) {
CpuPause ();
}
}
//=============================================================================
// SpiProtocolInit: sub_FFD8F09A
//=============================================================================
EFI_STATUS
EFIAPI
SpiProtocolInit (
OUT PCH_SPI_INSTANCE *SpiInstance
)
{
if (SpiInstance == NULL) {
return EFI_INVALID_PARAMETER;
}
SpiInstance->Signature = PCH_SPI_INSTANCE_SIGNATURE;
SpiInstance->PchSpiBar0 = (UINT32 *)(UINTN)PCH_SPI_BAR0;
return EFI_SUCCESS;
}
//=============================================================================
// PchInfoGetPchSeriesStr: sub_FFD8BD94
//=============================================================================
VOID
EFIAPI
PchInfoGetPchSeriesStr (
OUT CHAR8 *Buf,
IN UINTN BufSize
)
{
AsciiStrCpyS (Buf, BufSize, "Purley");
}
//=============================================================================
// PchInfoGetPchSteppingStr: sub_FFD8BB3A
//=============================================================================
VOID
EFIAPI
PchInfoGetPchSteppingStr (
OUT CHAR8 *Buf,
IN UINTN BufSize,
IN INT16 *DeviceId
)
{
Buf[0] = 'A' + (*DeviceId & 0x0F);
Buf[1] = '\0';
}
//=============================================================================
// PchInfoGetPchSkuStr: sub_FFD8C1B5
//=============================================================================
VOID
EFIAPI
PchInfoGetPchSkuStr (
OUT CHAR8 *Buf,
IN UINTN BufSize
)
{
AsciiStrCpyS (Buf, BufSize, "C620");
}