Newer
Older
AMI-Aptio-BIOS-Reversed / LenovoServerPkg / POSTStatus / MultiSkuDistinctionPei / MultiSkuDistinctionPei.md
@Ajax Dong Ajax Dong 2 days ago 7 KB Restructure the repo

MultiSkuDistinctionPei -- Multi-SKU Distinction PEI Module

Overview

This PEIM detects the platform SKU (Stock Keeping Unit / hardware variant) by
reading SKU configuration from CMOS and/or a GUID-extended HOB installed by
an earlier PEIM (likely from the CrystalRidge chipset initialization). It then
installs a PPI via EFI_PEI_SERVICES to advertise the SKU identity so that
downstream PEIMs can adapt their behavior.

Key Insight: The module has two code paths:

  • A "HOB-provisioned" path where a previous PEIM (CrystalRidge) writes SKU
    data into a GUID HOB with sentinel 0x55
  • A "default" path where SKU PPI is installed with a notification mechanism
    for delayed SKU provisioning

Module Information

Field Value
Module Name MultiSkuDistinctionPei.efi
PE File Index 0419
Architecture IA32 (32-bit)
Base Address 0xffe6b0f4
Image Size 0xaa0
Total Functions 19 (all renamed)
Total Strings 21
MD5 a9e8b3e80a18ca6defecd3a579772108
SHA256 40ba8d607cf770ea8ddf835906301ae8c3f03e4c7185a2e1f35d58c4f28bab6e

GUIDs Used

GUID Value Purpose
gSkuPeiServiceGuid {36232936-0e76-31c8-a13a-3af2fc1c3932} Debug print PPI service lookup
gSkuMatchGuid {8a0d6b86-64f3-4dc2-a483-4987-71dfb7fd} GUID-extended HOB identifier for SKU data
gSkuNotificationGuid {9a7174ce-f357-4142-abbf-31c6-a5440be0} PPI notification GUID used for default SKU path

Segment Layout

Segment Start End Size Permissions
HEADER 0xffe6b0f4 0xffe6b354 0x260 ---
.text 0xffe6b354 0xffe6b7b4 0x460 rx
.rdata 0xffe6b7b4 0xffe6baf4 0x340 r
.data 0xffe6baf4 0xffe6bb54 0x60 rw
.reloc 0xffe6bb54 0xffe6bb94 0x40 r
GAP 0xffe6bb94 0xffe6c0f4 0x560 rw

Function Map

Address Name Size Type Description
0xffe6b354 SetMem 21 leaf memset wrapper
0xffe6b374 SetMem32_Pair 32 library SetMem32 in reverse-order pairs
0xffe6b394 SetMem32 24 leaf memset32 wrapper
0xffe6b3b4 CopyMem 96 leaf memmove with overlap handling
0xffe6b414 _ModuleEntryPoint 116 complex Main entry alloc buffer, SkuInit, dispatch PPI
0xffe6b488 InstallSkuPpi 68 complex Install default or notification SKU PPI
0xffe6b4cc GetDebugInstance 49 wrapper Locate debug PPI via PeiServices->LocatePpi
0xffe6b4fd DebugPrint 42 complex Conditional print with level mask check
0xffe6b527 PeiServicesNotify 30 wrapper Call debug assert handler
0xffe6b545 SkuInit 54 complex Read 3 SKU bytes from CrystalRidge HOB
0xffe6b57b EntryPointStub 12 wrapper PPI callback -> InstallSkuPpi
0xffe6b587 GetSkuFromCmos 79 leaf Read SKU from CMOS 0x4A or HW reg 0xFEDAF0490
0xffe6b5d6 IsGuidMatch 100 complex Compare 2 GUIDs via ReadUnaligned64
0xffe6b63a GetHobList 110 complex Get HOB list via PeiServices->GetHobList
0xffe6b6a8 FindHobByType 69 complex Walk HOB list for type match
0xffe6b6ed FindMatchingHob 53 complex Find CrystalRidge GUID-extended HOB matching gSkuMatchGuid
0xffe6b722 GetPeiServices 50 complex Get PEI Services via IDT table pointer
0xffe6b754 ReadUnaligned64 44 wrapper Read 8 bytes from potentially unaligned ptr
0xffe6b780 ReadIdtr 36 leaf __sidt instruction wrapper

Call Flow

_ModuleEntryPoint (0xffe6b414)

  +-- (*PeiServices)->AllocatePages()   -- Allocate boot buffer

  +-- SkuInit() (0xffe6b545)
     +-- FindMatchingHob() (0xffe6b6ed)
           +-- GetHobList() (0xffe6b63a)
           |     +-- GetPeiServices() (0xffe6b722)
           |     |     +-- ReadIdtr() (0xffe6b780)
           |     +-- (*PeiServices)->GetHobList()
           +-- FindHobByType() (0xffe6b6a8)
           +-- IsGuidMatch() (0xffe6b5d6)
                 +-- ReadUnaligned64() (0xffe6b754) [x4]

  +-- [sentinel == 0x55] --> (*PeiServices)->InstallPpi (active path)
  +-- [sentinel != 0x55] --> InstallSkuPpi() (0xffe6b488)

        +-- DebugPrint()
     +-- GetDebugInstance() (0xffe6b4cc)
     |     +-- GetPeiServices()
     |     +-- (*PeiServices)->LocatePpi()
     +-- GetSkuFromCmos() (0xffe6b587) -- check debug mask

        +-- SkuInit()
        +-- (*PeiServices)->NotifyPpi() -- install default PPI

Execution Flow Details

Phase 1: Module Entry

  1. Allocate buffer: PeiServices->AllocatePages (EfiBootServicesData, 52, &Buffer)
  2. Write revision data: The allocated buffer receives platform revision data
    and a sentinel byte (0x55) at offset 16.
  3. SkuInit: Reads the CrystalRidge SKU HOB. If found, 3 SKU identifier
    bytes (at HOB offsets 48, 49, 50) are copied into a local buffer.
  4. Decision: If SkuBuffer[24] == 0x55 (sentinel present):
    • Install the active SKU PPI descriptor
    • This path means CrystalRidge-provisioned SKU data is already available
    • Otherwise: call InstallSkuPpi() for the default path

Phase 2: InstallSkuPpi (Default Path)

  1. Prints "InstallSkuPpi is called\n" via debug print
  2. Tries SkuInit() again (defensive)
  3. If SkuBuffer[24] != 0x55:
    • Installs the "default" PPI notification via PeiServices->NotifyPpi()
    • This causes EntryPointStub(0xffe6b57b) to fire when the PPI is installed
    • EntryPointStub re-enters InstallSkuPpi() recursively

SKU Detection: GetSkuFromCmos

Hardware-level SKU detection with CMOS fallback:

  1. CMOS register 0x4A: Read via I/O ports 0x70/0x71
    • NMI bit (0x80) is preserved from original CMOS index
  2. If value <= 3: Return directly (small SKU IDs 0-3)
    • value 0x00 -> return 0 (SKU not found)
    • value 0x01 -> return 1 (SKU found)
  3. If value == 0: Fallback to MMIO at 0xFEDAF0490
    • Mask bit 1, OR with 1
    • result = (MMIO & 2) | 1
    • If result is 0x01, SKU is valid
  4. If value == 0xFF: Return 0 (SKU invalid)
  5. Otherwise: Return EFI error codes

Library Dependencies (internal implementations)

Function EDK2 Source
SetMem MdePkg/Library/BaseMemoryLib
SetMem32_Pair MdePkg/Library/BaseMemoryLib
SetMem32 MdePkg/Library/BaseMemoryLib
CopyMem MdePkg/Library/BaseMemoryLib
ReadUnaligned64 MdePkg/Library/BaseLib/Unaligned.c
ReadIdtr MdePkg/Library/BaseLib/X86ReadIdtr.c
GetPeiServices MdePkg/Library/PeiServicesTablePointerLibIdt
GetHobList / FindHobByType / IsGuidMatch MdePkg/Library/PeiHobLib/HobLib.c
DebugPrint / GetDebugInstance / PeiServicesNotify MdePkg/Library/PeiDebugLib

Hardware Addresses Referenced

Address Purpose
0x70 (I/O) CMOS index register
0x71 (I/O) CMOS data register
0xFEDAF0490 (MMIO) Fallback SKU hardware register (LPC/Firmware Hub)

Notes

  • The module has no imported functions -- all dependencies are linked
    statically as internal implementations.
  • The PEI Services Table Pointer is obtained via the IDT pointer trick:
    the PEI Services pointer is stored 4 bytes before the IDT base address.
  • GUID comparison uses unaligned 64-bit reads instead of CompareGuid(),
    which is a common pattern in EDK2 BaseLib implementations where full GUID
    comparison is replaced with 2 x 64-bit integer comparisons.
  • The module is part of the Lenovo CrystalRidge platform initialization,
    providing SKU distinction so that subsequent PEIMs (especially those in
    the CrystalRidge PEI phase) can select the correct configuration for
    the detected hardware variant.
  • 32 functions renamed in total (was 18 unnamed + 1 entry point).