/*
*SystemBoardPpi.c
*Decompiled source for SystemBoardPpi.efi (index 0379)
*Source path: e:\hs\PurleyRpPkg\SystemBoard\Pei\SystemBoardPpi.c
*
*This module is a PEI (Pre-EFI Initialization) driver for Intel Purley
*platform system board management. It handles:
* - Board type detection (riser cards, backplane personalities)
* - PCIe slot configuration including hot-plug
* - GPIO-based riser card presence detection (left/right)
* - Clock generator programming via SMBUS
* - PCH SKU detection and initialization
* - IOU (IIO Global Data) configuration for PCIe bifurcation
*
*Build info:
*MD5: fd9853cf6bcba996cb976e29015c15fb
*SHA256: 8c96e3adac00618b1019f7d6cf0ac023bde5ed21198c7cf7b9b070bde66ba862
*Arch: IA-32
*Size: 0x9D20 (40,224 bytes)
*87 functions, 2 named, 85 unnamed
*/
#include <PiPei.h>
#include "SystemBoardPpi.h"
/*Forward declarations */
INT32 SystemBoardInit(VOID);
UINT8 DetectBoardType(VOID);
EFI_STATUS DetectBPType(OUT UINT8*, OUT UINT8*, OUT UINT8*, OUT UINT8*);
INT32 ConfigureRiserSlot(IN INT32, IN UINT8*, IN UINT8);
UINT8 IioGpioRiserConfig(IN INT32);
INT8 GetBoardInfo(VOID);
UINT32 GetPchSku(VOID);
UINT8 ConfigureHotPlugSlot(IN INT32, IN UINT8, IN INT8, IN UINT8, IN UINT8);
/*=============================================================================
*Module Entry Point - 0xFFDEB488
*============================================================================*/
EFI_STATUS EFIAPI ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
/*Phase 1: One-time initialization flag using PCI Express register at MMIO 0xFA004 */
if ((ReadPciExpress(1024068) & 0x80) == 0) {
ReadPciExpressRegister();
*(_BYTE *)(ReadPciExpressRegister() + 1024068) |= 0x80;
}
/*Phase 2: Board initialization */
SystemBoardInit();
/*Phase 3: Locate the IIO (Integrated IO) configuration PPI */
INT32 PeiServices = GetPeiServices();
INT32 Status = (*(INT32 ( **)(INT32, VOID *))(*(UINT32 *)PeiServices + 24))(
PeiServices,
&unk_FFDF2C44 /*Some configuration PPI GUID */
);
/*Phase 4: Check result */
if (Status < 0) {
DebugAssert(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
INT32 DebugInstance = GetDebugInstance();
if (DebugInstance) {
(*(VOID ( **)(const CHAR8 *, INT32, const CHAR8 *))(DebugInstance + 4))(
"e:\\hs\\PurleyRpPkg\\SystemBoard\\Pei\\SystemBoardPpi.c",
2843,
"!EFI_ERROR (Status)"
);
}
}
return Status;
}
/*=============================================================================
*SystemBoardInit - 0xFFDEC44B
*============================================================================*/
INT32 SystemBoardInit (
VOID
)
{
INT32 Status;
INT32 IioSkuData;
PVOID PcdPtr;
/*Get PCD pointer and set SKU */
PcdPtr = PeiPcdGetPtr();
(*(VOID ( **)(PVOID, UINT32))(PcdPtr + 60))(39, 0); /*Set SKU */
/*Check board type */
if (DetectBoardType() < 2) {
/*Board is standard (not a special riser/dev board) */
PcdPtr = PeiPcdGetPtr();
(*(VOID ( **)(PVOID, INT32))(PcdPtr + 60))(39, 1);
/*Locate SocketIioConfig PPI */
Status = LocatePpi(0, (VOID **)&IioSkuData);
if (Status >= 0) {
Status = (*(INT32 ( **)(INT32, const UINT16*, VOID*, UINT32, INT32*, INT32*))(IioSkuData))(
IioSkuData,
L"SocketIioConfig",
&unk_FFDF1FFC,
0,
&IioSkuData,
&Status
);
if (Status >= 0) {
SystemBoardInstallConfig(PcdPtr, 0);
}
}
} else {
/*Board is a special type - just clear SKU */
PcdPtr = PeiPcdGetPtr();
(*(VOID ( **)(PVOID, UINT32))(PcdPtr + 60))(39, 0);
}
return Status;
}
/*=============================================================================
*DetectBoardType - 0xFFDEB4FE
*============================================================================*/
UINT8 DetectBoardType (
VOID
)
{
EFI_GUID SetupGuid = SETUP_VARIABLE_GUID;
INT32 N814 = 814; /*Size of Setup data */
INT32 Result;
INT32 PeiServices;
PVOID PpiInterface;
UINT8 SetupData[816]; /*Stack buffer for setup variables */
/*Locate PPI database */
Result = (INT32)LocatePpi(0, &PpiInterface);
if (Result >= 0) {
/*Call the PPI to get Setup variable */
if ((*(INT32 ( **)(PVOID, const UINT16*, UINT32*, UINT32, INT32*, UINT8*))(PpiInterface))(
PpiInterface,
L"Setup",
&SetupGuid,
0,
&N814,
SetupData) >= 0) {
/*Return byte at offset 284 of Setup data (board type) */
return SetupData[284];
}
} else {
DebugAssert(0x80000000, "PeiServicesLocatePpi...(%r)\n", Result);
}
return 85; /*Default: 0x55 (unknown/no board) */
}
/*=============================================================================
*DetectBPType - 0xFFDEB58A
*============================================================================
*
*Detects backplane (BP) type through HECI/ME interface.
*Returns board personality type and riser configuration.
*
*Output parameters:
*BoardType - Board personality (0=standard, 4=riser)
*RiserType - Riser card type
*Unknown1 - Unknown config byte
*Unknown2 - Unknown config byte (often 0xFF or related to VPP)
*/
EFI_STATUS DetectBPType (
OUT UINT8 *BoardType,
OUT UINT8 *RiserType,
OUT UINT8 *Unknown1,
OUT UINT8 *Unknown2
)
{
UINT8 BpType = 0xFF;
INT32 N814 = 814;
UINT32 SetupGuid[4] = { 0xEC1D3A73, 0x4F44, 0x4B84, 0xA6A36B5E1D5B3D36 };
UINT8 SetupData[298];
EFI_STATUS Status;
INT32 PeiServices;
PVOID Ppi1, Ppi2;
*RiserType = 0xFF;
*Unknown2 = 0xFF;
*BoardType = 0;
*Unknown1 = 0;
/*Phase 1: Get BP type via HECI (using some PPI) */
PeiServices = GetPeiServices();
Status = (*(INT32 ( **)(INT32, VOID*, UINT32, UINT32, INT32*))(*(UINT32 *)PeiServices + 32))(
PeiServices,
&unk_FFDF1F9C, /*Some HECI/MCTP protocol GUID */
0,
0,
&Ppi1
);
if (Status >= 0) {
UINT8 Flag = 1;
Status = (*(INT32 ( **)(INT32, UINT32, UINT32, UINT32, UINT32, UINT32, UINT8*, UINT8*))(Ppi1 + 12))(
Ppi1,
46, /*HECI command */
0,
89, /*HECI sub-command / length */
0,
0,
&BpType,
&Flag
);
}
DebugAssert(0x80000000, "DetectBPType...(%r), BPType:0x%02x\n", Status, BpType);
/*Phase 2: Get Setup variable */
PeiServices = GetPeiServices();
Status = LocatePpi(0, &Ppi2);
if (Status < 0 ||
(Status = (*(INT32 ( **)(PVOID, const UINT16*, UINT32*, UINT32, INT32*, UINT8*))(Ppi2))(
Ppi2,
L"Setup",
SetupGuid,
0,
&N814,
SetupData),
Status < 0)) {
DebugAssert(0x80000000, "PeiServicesLocatePpi...(%r)\n", Status);
return Status;
}
/*Phase 3: Determine board personality based on BP type and platform */
BOOLEAN IsRiserCard = IsRiserCardPresent(); /*Check if riser is present */
BOOLEAN SomeFlag = IsPlatformRiserOverrideEnabled(); /*Platform-specific riser override */
if (IsRiserCard == 1) {
/*Riser card platform */
switch (BpType) {
case 1: /*Type 1 */
*BoardType = 0;
*RiserType = 2;
*Unknown2 = 6;
*Unknown1 = 0;
break;
case 8: /*Type 8 */
*BoardType = 4;
*RiserType = 4;
*Unknown2 = 4;
*Unknown1 = 0;
break;
case 10: /*Type 10 */
*BoardType = 4;
*Unknown1 = 0;
*RiserType = 0;
*Unknown2 = 0;
break;
default:
*BoardType = 0;
*Unknown1 = 0;
*Unknown2 = 0xFF;
*RiserType = 0xFF;
break;
}
} else {
/*Standard platform */
if (SomeFlag) {
if (!BpType) {
*BoardType = 0;
*RiserType = 4;
*Unknown1 = 0;
} else if (BpType != 9) {
*BoardType = 0;
*Unknown1 = 0;
if (BpType != 11)
goto end;
*BoardType = 0;
*RiserType = 4;
*Unknown1 = 0;
} else {
*BoardType = 4;
*RiserType = 8;
*Unknown1 = 0;
}
*Unknown2 = 0;
} else {
if (!BpType) {
*BoardType = 0;
*Unknown2 = 8;
*Unknown1 = 0;
*RiserType = 0xFF;
return 0;
}
*RiserType = 0xFF;
if (BpType == 9) {
*BoardType = 4;
*Unknown1 = 0;
} else {
*BoardType = 0;
*Unknown1 = 0;
if (BpType != 11)
goto end;
}
*Unknown2 = 8;
return 0;
}
}
end:
*Unknown2 = 0xFF;
*RiserType = 0xFF;
return 0;
}
/*=============================================================================
*ConfigureRiserSlot - 0xFFDEB7DF
*============================================================================
*
*Configures PCIe slot mapping for riser card installation.
*Slot tables contain 12-byte entries per slot.
*/
INT32 ConfigureRiserSlot (
IN INT32 BoardData,
IN UINT8 *SlotTable,
IN UINT8 SlotCount
)
{
UINT8 SlotIndex;
UINT8 ConfigVal;
/*Phase 1: Parse slot table entries (12 bytes each) */
if (SlotCount) {
UINT8 *Entry = SlotTable;
UINT8 Count = SlotCount;
do {
UINT8 SlotNum = *(Entry - 1); /*Slot index (0-based) */
/*Check if VPP is present for this slot */
if (Entry[10]) { /*VPP enable flag */
*(_BYTE *)(SlotNum + BoardData + 4350) = 1; /*VPP config */
*(_BYTE *)(SlotNum + BoardData + 4255) = 1; /*VPP config */
}
/*Skip 0xFF entries (empty slots) */
if (*Entry != 0xFF) {
*(_BYTE *)(SlotNum + BoardData + 11) = 1; /*Slot present */
*(_WORD *)(BoardData + 2 *SlotNum + 95) = *((UINT16 *)Entry); /*Slot number map */
*(_BYTE *)(SlotNum + BoardData + 263) = Entry[1]; /*Slot attribute */
if (Entry[2] != 0xFF) {
*(_BYTE *)(SlotNum + BoardData + 347) = Entry[2]; /*Slot config */
*(_BYTE *)(SlotNum + BoardData + 431) = Entry[3]; /*Slot config */
}
/*Configure hot-plug if enabled */
if (Entry[4] || *(_BYTE *)(SlotNum + BoardData + 515)) {
ConfigureHotPlugSlot(BoardData, SlotNum, Entry[8], Entry[9], 0);
}
}
Entry += 12;
} while (--Count);
}
/*Phase 2: Determine riser card type and slot mapping */
UINT8 RiserPresence = GetRiserCardPresence(); /*Check riser presence */
UINT8 SomeConfig = 0;
ReadBoardSlotConfig((CHAR8 *)&SlotCount + 3, &SomeConfig);
*(_WORD *)(BoardData + 109) = 9; /*Default max slots */
if (RiserPresence == 1) {
/*Riser card type 1 detected */
DebugAssert(0x80000000, "1U\n");
*(_WORD *)(BoardData + 113) = 2; /*Right riser slot count */
*(_WORD *)(BoardData + 97) = 1; /*Slot starting number */
*(_WORD *)(BoardData + 147) = 3; /*Slot mapping */
/*Fall through to phase 3 */
goto map_slots;
}
/*Riser card type 2 */
DebugAssert(0x80000000, "2U\n");
UINT8 Riser1Id = ReadLeftRiserCardId(); /*Read riser 1 ID */
DebugAssert(0x80000000, "RiserCard1 ID:0x%x\n", Riser1Id);
UINT8 Riser2Id = ReadRightRiserCardId(); /*Read riser 2 ID */
DebugAssert(0x80000000, "RiserCard2 ID:0x%x\n", Riser2Id);
/*Map riser 1 type */
switch (Riser1Id - 8) {
case 0: /*Riser type 8 -> standard */
*(_WORD *)(BoardData + 113) = 2;
*(_WORD *)(BoardData + 117) = 1;
break;
case 2: /*Riser type 10 -> special */
*(_WORD *)(BoardData + 113) = 1;
break;
default:
*(_WORD *)(BoardData + 97) = 0;
*(_WORD *)(BoardData + 113) = 0;
*(_WORD *)(BoardData + 117) = 0;
break;
}
*(_WORD *)(BoardData + 97) = 3; /*Default slot start */
*(_WORD *)(BoardData + 101) = 4; /*Slot 4 base */
/*Map riser 2 type */
switch (Riser2Id - 2) {
case 0:
*(_WORD *)(BoardData + 147) = 5;
*(_WORD *)(BoardData + 151) = 6;
break;
case 2:
*(_WORD *)(BoardData + 147) = 5; /*Fall through from default */
break;
default:
*(_WORD *)(BoardData + 147) = 0;
*(_WORD *)(BoardData + 151) = 0;
break;
}
map_slots:
/*Phase 3: Map slot numbers based on board type */
UINT8 BoardTypeFlag;
UINT8 ConfigByte;
EFI_STATUS Status = DetectBPType(&BoardTypeFlag, &ConfigByte, &Unknown1, &Unknown2);
if (Status >= 0) {
UINT8 BoardType = DetectBoardType();
UINT8 SlotBase;
if (!BoardType || BoardType == 1)
SlotBase = 11; /*Board type 0 or 1 */
else SlotBase = 10; /*Board type >= 2 */
if (RiserPresence == 1) {
/*Type 1 riser: assign slot numbers */
if (IsPlatformRiserOverrideEnabled(1, 0)) { /*Some platform check */
UINT8 I = ConfigByte + 1;
if (I <= 12) {
UINT16 *SlotMap = (_WORD *)(BoardData + 2 *I + 137);
do {
if (I < 5 || I > 8) /*Skip slots 5-8, they're fixed */
*SlotMap = SlotBase++;
I++;
SlotMap++;
} while (I <= 12);
}
} else {
/*No override from BP detection */
if (HIBYTE(SlotCount)) {
*(_WORD *)(BoardData + 97) = SlotBase + ConfigByte;
*(_WORD *)(BoardData + 99) = SlotBase + ConfigByte + 1;
}
if (SomeConfig) {
*(_WORD *)(BoardData + 113) = SlotBase + ConfigByte + 2;
*(_WORD *)(BoardData + 115) = SlotBase + ConfigByte + 3;
}
}
} else {
/*Type 2 riser */
if (HIBYTE(SlotCount)) {
*(_WORD *)(BoardData + 97) = SlotBase + ConfigByte;
*(_WORD *)(BoardData + 99) = SlotBase + ConfigByte + 1;
}
if (SomeConfig) {
*(_WORD *)(BoardData + 101) = SlotBase + ConfigByte + 2;
*(_WORD *)(BoardData + 103) = SlotBase + ConfigByte + 3;
}
/*Same slot map logic */
if (IsPlatformRiserOverrideEnabled(SlotBase, ConfigByte)) {
UINT8 I = ConfigByte + 1;
if (I <= 12) {
UINT16 *SlotMap = (_WORD *)(BoardData + 2 *I + 137);
do {
if (I < 5 || I > 8)
*SlotMap = SlotBase++;
I++;
SlotMap++;
} while (I <= 12);
}
}
}
}
return Status;
}
/*=============================================================================
*IioGpioRiserConfig - 0xFFDEBDFA
*============================================================================
*
*Reads GPIO pins for left/right riser card detection and sets up
*IIO (Integrated IO) configuration for PCIe bifurcation.
*
*This function:
*1. Reads GPIO state for right and left riser cards
*2. Detects riser card presence, hot-plug capability, wing config
*3. Configures IOUs based on detected riser personality
*4. Programs GPIO-based IOU config into IIO global data
*/
UINT8 IioGpioRiserConfig (
IN INT32 IioGlobalData
)
{
UINT32 RiserCfg[4] = { 0 };
INT32 BroadwayConfigCount = 0;
UINT8 CurrentConfigIOU0 = *(_BYTE *)(IioGlobalData + 1187); /*ConfigIOU0 */
UINT8 CurrentConfigIOU2 = *(_BYTE *)(IioGlobalData + 1195); /*ConfigIOU2 */
/*Step 1: Get QAT GPIO value (for QAT accelerator presence) */
INT32 QatGpio = 0;
GpioGetInputValue(GPIO_PAD_QAT, &QatGpio); /*0x01010003 */
DebugAssert(64, "QAT GPIO: %d\n", QatGpio);
/*Step 2: Determine SKU personality type */
UINT8 SkuPersonality;
UINT8 Personality7446 = *(_BYTE *)(IioGlobalData + 7446);
UINT8 Personality7447 = *(_BYTE *)(IioGlobalData + 7447);
if (Personality7446 == 3) {
if (Personality7447 == 3)
SkuPersonality = 1; /*Type 3,3 -> 1 */
else SkuPersonality = 2; /*Type 3,other -> 2 */
} else if (Personality7447 == 3) {
SkuPersonality = 3; /*Type other,3 -> 3 */
} else {
SkuPersonality = 0; /*Default */
}
DebugAssert(0x80000000, "SKU Personality Type: %d\n", SkuPersonality);
/*Step 3: Get riser card configuration */
INT32 BroadwayCfgResult = 0;
UINT8 BroadwayPersonality = 0;
GetBroadwayPersonality(&BroadwayPersonality, &CurrentConfigIOU2, SkuPersonality);
if (BroadwayPersonality == 1) {
/*Broadway (dual-riser) personality */
/*Read GPIO for RIGHT riser: Present, HotPlugConf, WingConf, Slot9En */
INT32 GpioVal;
GpioGetInputValue(GPIO_PAD_RIGHT_PRESENT, &GpioVal); /*0x01010004 */
CurrentConfigIOU2 ^= (CurrentConfigIOU2 ^ GpioVal) & 1;
GpioGetInputValue(GPIO_PAD_RIGHT_HOTPLUG, &GpioVal); /*0x0102000F */
CurrentConfigIOU2 ^= (CurrentConfigIOU2 ^ (GpioVal *2)) & 2;
GpioGetInputValue(GPIO_PAD_RIGHT_WINGCONF, &GpioVal); /*0x01020010 */
CurrentConfigIOU2 ^= (CurrentConfigIOU2 ^ (GpioVal *4)) & 4;
GpioGetInputValue(GPIO_PAD_RIGHT_SLOT9EN, &GpioVal); /*0x01020011 */
CurrentConfigIOU2 ^= (CurrentConfigIOU2 ^ (GpioVal *8)) & 8;
DebugAssert(64,
"GPIO Right riser information: PresentSignal=%x, HotPlugConf=%x, WingConf=%x, Slot9En=%x\n",
CurrentConfigIOU2 & 1, (CurrentConfigIOU2 >> 1) & 1,
(CurrentConfigIOU2 >> 2) & 1, (CurrentConfigIOU2 >> 3) & 1);
/*Read GPIO for LEFT riser */
UINT8 LeftConfig;
GpioGetInputValue(GPIO_PAD_LEFT_PRESENT, &GpioVal); /*0x01010005 */
LeftConfig = (GpioVal ^ CurrentConfigIOU0) & 1 ^ CurrentConfigIOU0;
GpioGetInputValue(GPIO_PAD_LEFT_HOTPLUG, &GpioVal); /*0x01020012 */
LeftConfig = (LeftConfig ^ (GpioVal *2)) & 2 ^ LeftConfig;
GpioGetInputValue(GPIO_PAD_LEFT_WINGCONF, &GpioVal); /*0x01020013 */
LeftConfig = (LeftConfig ^ (GpioVal *4)) & 4 ^ LeftConfig;
GpioGetInputValue(GPIO_PAD_LEFT_SLOT9EN, &GpioVal); /*0x01010015 */
LeftConfig = (LeftConfig ^ (GpioVal *8)) & 8 ^ LeftConfig;
DebugAssert(64,
"GPIO Left riser information: PresentSignal=%x, HotPlugConf=%x, WingConf=%x, Slot9En=%x\n",
LeftConfig & 1, (LeftConfig >> 1) & 1,
(LeftConfig >> 2) & 1, (LeftConfig >> 3) & 1);
/*Step 4: Configure IOU mappings based on riser presence */
if (QatGpio == 0) {
*(_BYTE *)(IioGlobalData + 1187) = CurrentConfigIOU0;
}
if (BroadwayPersonality == 1) {
BroadwayConfigCount = 9;
if (QatGpio != 0) {
/*QAT present - check slot 9 configuration for both risers */
if ((CurrentConfigIOU2 & 8) && (LeftConfig & 8)) {
/*Both risers have slot 9 enabled -> 4x4x4x4 bifurcation */
*(_BYTE *)(IioGlobalData + 7833) = 4;
*(_BYTE *)(IioGlobalData + 1187) = 0;
*(_BYTE *)(IioGlobalData + 7834) = 4;
*(_BYTE *)(IioGlobalData + 7835) = 4;
*(_BYTE *)(IioGlobalData + 7836) = 4;
}
/*Configure right riser mapping */
if (!(CurrentConfigIOU2 & 1)) {
/*Right riser present */
*(_BYTE *)(IioGlobalData + 20) = 1;
*(_BYTE *)(IioGlobalData + 79) = 1;
*(_BYTE *)(IioGlobalData + 83) = 1;
if (CurrentConfigIOU2 & 4) {
/*Wing configuration present */
*(_WORD *)(IioGlobalData + 113) = 2;
*(_WORD *)(IioGlobalData + 231) = 3;
*(WORD *)(IioGlobalData + 239) = 1;
if (CurrentConfigIOU2 & 2) {
/*Hot-plug enabled - configure slots */
ConfigureHotPlugSlot(IioGlobalData, 9, 0, 64, 0);
ConfigureHotPlugSlot(IioGlobalData, 68, 1, 64, 0);
ConfigureHotPlugSlot(IioGlobalData, 72, 0, 64, 0);
}
} else {
/*No wing config - standard */
*(_WORD *)(IioGlobalData + 113) = 1;
*(_WORD *)(IioGlobalData + 231) = 4;
*(_WORD *)(IioGlobalData + 239) = 2;
}
}
/*Configure left riser mapping */
if (!(LeftConfig & 1)) {
/*Left riser present */
*(_BYTE *)(IioGlobalData + 33) = 1;
*(_BYTE *)(IioGlobalData + 37) = 1;
*(_BYTE *)(IioGlobalData + 54) = 1;
*(_BYTE *)(IioGlobalData + 62) = 1;
if (LeftConfig & 4) {
/*Left wing configuration present */
*(_WORD *)(IioGlobalData + 139) = 5;
*(_WORD *)(IioGlobalData + 147) = 7;
*(_WORD *)(IioGlobalData + 181) = 8;
*(_WORD *)(IioGlobalData + 197) = 6;
if (LeftConfig & 2) {
/*Hot-plug enabled */
ConfigureHotPlugSlot(IioGlobalData, 22, 0, 66, 0);
ConfigureHotPlugSlot(IioGlobalData, 26, 1, 66, 0);
ConfigureHotPlugSlot(IioGlobalData, 43, 1, 66, 0);
ConfigureHotPlugSlot(IioGlobalData, 51, 0, 66, 0);
}
} else {
/*No wing - standard */
*(_WORD *)(IioGlobalData + 139) = 7;
*(_WORD *)(IioGlobalData + 147) = 5;
*(_WORD *)(IioGlobalData + 181) = 6;
*(_WORD *)(IioGlobalData + 197) = 8;
}
}
} else {
/*QAT not present, simpler config */
if (!(CurrentConfigIOU2 & 1)) {
*(_BYTE *)(IioGlobalData + 12) = 1;
/*goto simple_config */
}
/*Apply 4-wide config */
*(_BYTE *)(IioGlobalData + 7833) = 4;
/*Fall through to simple config */
}
}
}
/*Step 5: Apply IIO IOU configuration if Broadway config table is present */
if (BroadwayConfigCount) {
/*Read board config (BroadwayConfig) via I2C/SMBUS */
UINT8 BroadwayCfg[4] = { 0 };
ReadBroadwayConfiguration(SkuPersonality, BroadwayCfg);
DebugAssert(64, "Broadway Config: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
BroadwayCfg[0], BroadwayCfg[1], BroadwayCfg[2], BroadwayCfg[3]);
/*Apply configuration for each Broadway entry */
for (UINT8 i = 0; i < 3; i++) {
UINT8 EntryType = BroadwayCfg[2]; /*Entry type */
if (EntryType == 4)
break; /*End marker */
UINT8 EntryValue = (*(&BroadwayCfg[0] + EntryType)) & 7;
if (EntryValue != 7) {
UINT8 EntryTarget = BroadwayCfg[1];
if (EntryTarget == 0) {
/*Program ConfigIOU0 */
*(_BYTE *)(*(UINT32 *)BroadwayCfg + IioGlobalData + 1187) = EntryValue;
DebugAssert(0x80000000,
"IioGlobalData->SetupData.ConfigIOU0[%x] = %x\n",
*(UINT32 *)BroadwayCfg,
*(UINT8 *)(*(UINT32 *)BroadwayCfg + IioGlobalData + 1187));
} else if (EntryTarget == 1) {
/*Program ConfigIOU1 */
*(_BYTE *)(*(UINT32 *)BroadwayCfg + IioGlobalData + 1191) = EntryValue;
DebugAssert(0x80000000,
"IioGlobalData->SetupData.ConfigIOU1[%x] = %x\n",
*(UINT32 *)BroadwayCfg,
*(UINT8 *)(*(UINT32 *)BroadwayCfg + IioGlobalData + 1191));
} else if (EntryTarget == 2) {
/*Program ConfigIOU2 */
*(_BYTE *)(*(UINT32 *)BroadwayCfg + IioGlobalData + 1195) = EntryValue;
DebugAssert(0x80000000,
"IioGlobalData->SetupData.ConfigIOU2[%x] = %x\n",
*(UINT32 *)BroadwayCfg,
*(UINT8 *)(*(UINT32 *)BroadwayCfg + IioGlobalData + 1195));
}
}
BroadwayCfg += 3; /*Fixed width entries */
}
}
return Personality7446;
}
/*=============================================================================
*ConfigureHotPlugSlot - 0xFFDED8B0
*============================================================================
*
*Configures a single PCIe slot for hot-plug operation.
*Sets VPP (Vaux/Power) configuration and slot flags.
*/
UINT8 ConfigureHotPlugSlot (
IN INT32 BoardData,
IN UINT8 SlotIndex,
IN INT8 VppValue,
IN UINT8 VppValue2,
IN UINT8 SlotType
)
{
UINT8 Index = SlotIndex;
/*Set slot flags */
*(_BYTE *)(Index + BoardData + 515) = 1;
*(_BYTE *)(Index + BoardData + 767) = 1;
*(_BYTE *)(Index + BoardData + 683) = 1;
*(_BYTE *)(Index + BoardData + 851) = 1;
*(_BYTE *)(Index + BoardData + 1019) = 1;
*(_BYTE *)(Index + BoardData + 935) = 1;
if (SlotType == 4) {
/*Type 4 slot: clear all VPP config */
*(_BYTE *)(Index + BoardData + 767) = 0;
*(_BYTE *)(Index + BoardData + 683) = 0;
*(_BYTE *)(Index + BoardData + 1019) = 0;
*(_BYTE *)(Index + BoardData + 935) = 0;
*(_BYTE *)(Index + BoardData + 851) = 0;
}
if (SlotType == 3) {
/*Type 3 slot: partial */
*(_BYTE *)(Index + BoardData + 1019) = 0;
*(_BYTE *)(Index + BoardData + 935) = PeiPcdGetPtr()[4](39); /*Read PCD SKU */
*(_BYTE *)(Index + BoardData + 851) = 0;
}
if (SlotType != 4 && SlotType != 3) {
/*Slot type 0,1,2: full VPP config */
*(_BYTE *)(Index + BoardData + 599) = 1;
}
if (SlotType != 4 && SlotType != 3) {
/*Type 3 special handling */
*(_BYTE *)(Index + BoardData + 767) = 1;
*(_BYTE *)(Index + BoardData + 683) = 1;
*(_BYTE *)(Index + BoardData + 1019) = 0;
*(_BYTE *)(Index + BoardData + 935) = PeiPcdGetPtr()[4](39);
*(_BYTE *)(Index + BoardData + 851) = 0;
*(_BYTE *)(Index + BoardData + 599) = 1;
}
if (VppValue == -1) {
DebugAssert(0x80000000, "PCIE HOT Plug. Missing VPP values on slot table\n");
return VppValue2;
}
*(_BYTE *)(Index + BoardData + 2414) = VppValue;
*(_BYTE *)(Index + BoardData + 2330) = 1;
*(_BYTE *)(Index + BoardData + 2498) = VppValue2;
return VppValue2;
}
/*=============================================================================
*GetBoardInfo - 0xFFDEBACF
*============================================================================
*
*Gets board information from the HOB (Hand-Off Block).
*Returns byte at offset 61 of the board HOB, or -1 on failure.
*/
INT8 GetBoardInfo (
VOID
)
{
/*Look up board info HOB */
PVOID BoardHob = GetBoardInfoHob(&gSystemBoardInfoHobGuid, this);
if (BoardHob) {
return *(_BYTE *)(BoardHob + 61);
}
/*HOB not found - assert */
INT32 DebugInstance = GetDebugInstance();
if (DebugInstance) {
(*(VOID ( **)(const CHAR8 *, INT32, const CHAR8 *))(DebugInstance + 4))(
"e:\\hs\\PurleyRpPkg\\SystemBoard\\Pei\\SystemBoardPpi.c",
1929,
"GuidHob != ((void *) 0)"
);
}
return -1;
}
/*=============================================================================
*GetPchSku - 0xFFDEE721
*============================================================================
*
*Reads PCH LpcDeviceId and returns the SKU type.
*
*Returns:
*1 - Server PCH (LpcDeviceId 0xA1C0-0xA1CF, 0xA243, 0xA240-0xA24F)
*2 - Workstation PCH (LpcDeviceId 0x9D40-0x9D43, 0x9D46, 0x9D48)
*3 - Unknown (unsupported PCH)
*/
UINT32 GetPchSku (
VOID
)
{
UINT32 Result = 3;
/*Get PCH LPC device ID via PciExpress */
INT32 SmbusBase = SmbusPciBaseAddr(0);
UINT16 LpcDeviceId = ReadPciDeviceId16(SmbusBase + 2);
/*Check for Server PCH devices */
if ((LpcDeviceId >= 0xA1C0 && LpcDeviceId <= 0xA1CF) ||
LpcDeviceId == 0xA243 ||
(LpcDeviceId >= 0xA240 && LpcDeviceId <= 0xA24F)) {
Result = 1; /*Server PCH (Lewisburg) */
}
/*Check for Workstation PCH devices */
else if (LpcDeviceId == 0x9D40 || LpcDeviceId == 0x9D41 ||
LpcDeviceId == 0x9D42 || LpcDeviceId == 0x9D43 ||
LpcDeviceId == 0x9D46 || LpcDeviceId == 0x9D48) {
Result = 2; /*Workstation PCH (Sunrise Point) */
}
else {
DebugAssert(0x80000000, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", LpcDeviceId);
INT32 DebugInstance = GetDebugInstance();
if (DebugInstance) {
(*(VOID ( **)(const CHAR8 *, INT32, const CHAR8 *))(DebugInstance + 4))(
"e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmPchInfoLib\\PchInfoLib.c",
252,
"((BOOLEAN)(0==1))"
);
}
}
return Result;
}
/*=============================================================================
*PeiPcdGetPtr - 0xFFDEE900
*============================================================================
*
*Gets PCD (Platform Configuration Database) pointer via the PcdPpi.
*/
VOID *PeiPcdGetPtr (
VOID
)
{
VOID *PcdPtr;
EFI_STATUS Status = LocatePpi(0, (VOID **)&PcdPtr);
if (Status < 0) {
DebugAssert(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
INT32 DebugInstance = GetDebugInstance();
if (DebugInstance) {
(*(VOID ( **)(const CHAR8 *, INT32, const CHAR8 *))(DebugInstance + 4))(
"e:\\hs\\MdePkg\\Library\\PeiPcdLib\\PeiPcdLib.c",
49,
"!EFI_ERROR (Status)"
);
}
}
return PcdPtr;
}
/*=============================================================================
*Static Helper Functions
*============================================================================*/
/*GetPeiServices - 0xFFDEE8CE */
INTN GetPeiServices (VOID)
{
PEI_SERVICES_PPI PeiServicesPpi;
LocatePeiServicesPpi(&PeiServicesPpi);
INTN PeiServices = *(UINT32 *)(*(UINT32 *)&PeiServicesPpi[2] - 4);
if (!PeiServices) {
ReportNullPointerAssertion("PeiServices != ((void *) 0)");
}
return PeiServices;
}
/*LocatePpi - 0xFFDEEB3C */
EFI_STATUS LocatePpi (IN EFI_GUID *Guid, OUT VOID **PpiInterface)
{
INTN PeiServices = GetPeiServices();
return (*(INTN ( **)(INTN, INTN, UINT32, INTN, INTN))(*(UINT32 *)PeiServices + 32))(
PeiServices,
Guid,
0,
PpiInterface
);
}
/*PchPcrRead32 - 0xFFDEFC88
*Reads 32-bit PCH private configuration register via memory-mapped IO.
*PID is the PCH segment identifier, offset must be 4-byte aligned. */
EFI_STATUS PchPcrRead32 (IN UINT8 Pid, IN UINT16 Offset, IN INT32 Unused, OUT UINT32 *Data)
{
if (Offset & 3) {
DebugAssert(0x80000000, "PchPcrRead error. Invalid Offset: %x Size: %x", Offset, 4);
INT32 DebugInstance = GetDebugInstance();
if (DebugInstance) {
(*(VOID ( **)(const CHAR8 *, INT32, const CHAR8 *))(DebugInstance + 4))(
"e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmPchPcrLib\\PchPcrLib.c",
57,
"((BOOLEAN)(0==1))"
);
}
return EFI_INVALID_PARAMETER;
}
/*PCH PCR memory-mapped base = 0xFD000000 + (PID << 16) + Offset */
*Data = *(UINT32 *)(Offset | ((Pid | 0xFFFFFD00) << 16));
return EFI_SUCCESS;
}