Newer
Older
AMI-Aptio-BIOS-Reversed / SpsPei / SpsPei.md
@Ajax Dong Ajax Dong 2 days ago 7 KB Init

SpsPei

Function Table

Address Name Description
InternalSetMem32_Block
TruncateTo32
ReadIdtr
ReadUnaligned64
WriteUnaligned64
GetTimestampFrequency
IoRead16
IoWrite16
IoRead32
SpsDebugPrint
DebugAssert
GetDebugLevel
PcdGet32
PcdCallbackInit
PcdGetFromProtocol
PchPwrmBaseGet
GetPchSkuType
SetPchMmioRange
PeiServicesLocatePpi
HobIsMatchingGuid
GetMeFs1FromHob
IsSpsFw
IsSpsNormalModeS3
MicroSecondDelaySpin
MicroSecondDelay
WaitForMeNormalOrRecovery
WaitForMeFwInitComplete
WaitForMeResetCounterChange
SetNmBootMode
SpsS3Path
SpsNonS3Path
FinalizeSpsInit
PpiNotifyHeciReady
ExecutePreDidReset
IccSetGetCurrentClockingMode
PeiHeciSetSscAlternate
SpsPeiEntryPoint
ModuleEntryPoint
GetBootMode
SetWatchdogTimer
External GUIDs defined in the .data section
extern EFI_GUID gHeci1PpiGuid;
Notify descriptors for PPI registration
extern EFI_PEI_NOTIFY_DESCRIPTOR mS3NotifyDesc;
Library Wrappers / Internal Helpers
Debug and Assert
Level 0-3: directly interpret
if (Value == 0) {
Value > 3: check if n3_0 is zero (backup from memory)
if (n3_0 == 0) {
Read fallback from memory-mapped register
Value *= ((volatile UINT8 *)0xFDAF0490 & 2) 1;**
EFI_D_WARN only
PCD Access via PEI PCD Protocol
PCD call-back data structures (used for lazy initialization)
STATIC UINT32 mPcdTable[] = { 0 };
External table path
PcdPtr = (UINT32 )((UINT32 )((UINTN)PcdEntry + 12) +
Local protocol path
if (PcdProtocol->GetSize (PcdGetPtr) != 0) {
PCH / Platform Helpers
Read LPC device ID from PCH config space at Bus 0, Dev 1F, Func 0
LpcDeviceId = IoRead16 (GetMeFwHob (31, 2));
Extract PWRM base from the same config space
mPchSkuType = 1;
mPchSkuType = 2;
HECI (Host Embedded Controller Interface) Access
ME Firmware HOB Access
Error path: assert MeFwHob->Group[0].FunNumber == HECI1_DEVICE
DEBUG ((EFI_D_ERROR, "HECI: GetMeFs1FromHob() Can't read correctly MeFwHob info\n"));
Check DWR flow
if (((volatile UINT32 )(PwrmBase + 300) & 0x8000) != 0) {
HOB not yet available; read from HOB directly
MeFs1 = GetMeFs1FromHob ();
Valid FSM state
if ((MeFs1 & MEFS1_ME_STATE_MASK) == 4) {
TAP }
Normal case 1: // Debug
Manufacturing return 255;
SPS return 1;
No ME firmware state
HOB Building
Timer / Delay
ME Message Functions
Read boot mode for context
BootMode = 4;
Validate ME state
switch ((MeStatus & MEFS1_ME_STATE_MASK) - 2) {
Recovery GetMeFwHob (0);
Normal (5 - 2 = 3)
Wait for ME firmware init
Status = WaitForMeFwInitComplete (GetSpsPolicyPpi ());
Locate HECI PPI
Status = PeiServicesLocatePpi (&gHeci1PpiGuid, (VOID )&HeciPpi);**
Save and adjust MMIO range
MmioRange = (volatile UINT32 )PCH_MMIO_RANGE_REGISTER;
Check if END_OF_POST should be sent
if (GetHeciPpi (NULL) != NULL &&
Restore flags
Get SPS policy
SpsPolicy = (SPS_POLICY_PPI *)GetSpsPolicyPpi ();
Status = WaitForMeFwInitComplete (SpsPolicy);
Locate the HECI PPI
GetMeFwHob (0);
Reset HECI and send ME-BIOS Interface Version request
Retry loop for interface version negotiation
for (RetryCount = 0; RetryCount < HECI_MSG_GET_MEBIOS_RETRY; RetryCount++) {
Success - interface version negotiated
Configure Node Manager (NM) if enabled
if ((FeatureSet & FEATURE_NODE_MANAGER) != 0) {
NMFS configured
if (SpsPolicy != NULL) {
Initialize HECI-2
if (EFI_ERROR (PeiServicesLocatePpi (&gHeci1PpiGuid, (VOID )&IccPpi)) **
Apply ICC clock settings
if (IccSetGetCurrentClockingMode (NULL) >= 0) {
Apply ICC clock settings if feature enabled
if ((FeatureSet & FEATURE_ICC_CLOCK_SETTINGS) != 0 &&
Finalize SPS init with HOB publishing
FinalizeSpsInit (
Data buffer published in the HOB (16 bytes)
struct {
Build the SPS info HOB via PEI services
SpsInfoHob = (SPS_INFO_HOB *)HobCreateSpsInfo (
Verify SPS info HOB was registered
if (HobGetGuid (&gSpsInfoHobGuid) == NULL) {
Locate existing SPS info HOB
SpsInfoHob = (SPS_INFO_HOB *)HobGetGuid (&gSpsInfoHobGuid);
Store notify descriptor and PPI pointer in the HOB at known offsets
Offset +35: low byte of NotifyDesc
Offset +36: low byte of Ppi
Capture pre-reset ME state
MeFs1Pre = (volatile UINT32 )(GetMeFwHob (0) + 64);
Build and send Pre-DID reset MKHI message
Check reset response
if **((MkhiMsgBuf[0] & 0x7F00) != 0 **
Wait for reset counter to change
Status = WaitForMeResetCounterChange (
Wait for ME to return to Normal or Recovery state
Status = WaitForMeNormalOrRecovery (&Timeout);
ICC (Integrated Clock Control)
ICC header: signature 0x40000, version, response fields
ICC_MESSAGE_BUFFER LocalBuf;
Locate HECI PPI and send ICC command
ME Entry Point
Step 1: Verify ME firmware is SPS
if (IsSpsFw () != 1) {
Step 2: Read boot mode
Step 3: Check pre-DID reset policy
DEBUG ((EFI_D_INFO, " execution\n"));
ME in recovery mode: re-initialize
DEBUG ((EFI_D_WARN
Step 4: Branch to S3 or non-S3 path
if (BootMode == BOOT_MODE_S3_RESUME) {
S3 resume path
DEBUG ((EFI_D_INFO, "[SPS] S3 resume path\n"));
DEBUG ((EFI_D_INFO, "[SPS] Non S3 boot path\n"));
FinalizeSpsInit (0, 0, 0, 0, 0);
Module Entry Point (PEI)
Check whether bit 7 of the marker byte is set.
if ((CHAR8 )(GetBootMode () + 1024068) >= 0) {
First call: set watchdog timer (1280ms)
SetWatchdogTimer ();
Mark as initialized
PPI Notify Descriptors (in .data section)
EFI_PEI_NOTIFY_DESCRIPTOR at 0xFFDA68B0 (for S3 path)
Notify = SpsS3Path
EFI_PEI_NOTIFY_DESCRIPTOR mS3NotifyDesc = {
EFI_PEI_NOTIFY_DESCRIPTOR at 0xFFDA68BC (for Non-S3 path)
Notify = PpiNotifyHeciReady
EFI_PEI_NOTIFY_DESCRIPTOR mNonS3NotifyDesc = {

Generated by HR650X BIOS Decompilation Project