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

PchSerialGpio

Function Table

Address Name Description
GpioGetMioBase
GpioReadReg
GpioWriteReg
GpioPollSgpioReady
GpioIsPadValid
GpioValidateGroup
GpioValidatePin
RegisterSerialGpio
SetSerialGpioAltFunc
GpioWriteSgpioWord
GpioWriteSgpioPartialWord
UnregisterSerialGpio
GpioGetPadConfig
GpioPackDw1Value
GpioSetPadConfig
GpioUnpackDw0Value
GpioSetPadBlinkMode
GpioSetPadGpiMode
GpioCheckPadOwnership
GpioGetDw0RegAddress
GpioIsSgpioBusy
GpioGetPchStepping
PchSerialGpioEntryPoint
ModuleEntryPoint
Globals //
0x2E48 EFI_SYSTEM_TABLE *gSystemTable = NULL; // 0x2E38
0x2E40 EFI_RUNTIME_SERVICES *gRuntimeServices = NULL; // 0x2E50
0x2E60 VOID *gmMciUsra = NULL; // 0x2E68
0x2E70 VOID *gPcd = NULL; // 0x2E80
0x2E78 UINT32 gPchStepping = 3; // 0x2E30 (PCH_SSTEPPING_UNKNOWN = 3)
GPIO Group Information Table (GpioGroupnfo[])
13 entries, 60 ytes each, at 0x2B20
For fll struct layout, see GGIO_GROUP_INFO in PPchSerialGpio.h
GLOBAL GPI_O_GROUP_INFO mGpioGroupTable = (GPIO_GROUP_INFO)0x2B20;
Numbe of groups
GGIO MMIO register offsets used by ths driver
0x210 - Pad confg DW DW0 register
0x20C - Pad DW0 mas register
0x204 - Pad DW0 value register
LBG return (GpioPad & 0xFF000000) == 0x01000000;
SLBG return (GpioPad & 0xFF000000) == 0x02000000;
First call - detect PCH stepping
PPI config B0:D31:F0, offset 2
LPC DeviceId in 0x5E40-0x5E7F range -> LBB
LPC DeiceId in SLBG range
Validate protocol signature (CR macro - offset -40 bytes from
the functon pointer passed as 'This'
Check if a pin is alrady registered
Contine anyway (nofatal)
Detrmine GPIO group based on PCH stepping
n515 = 515 (0x203) for SBBG, 259 (0x103) for LBG
Read current DW0_REG and DW0_MAK registers
Build full GpioPad from function, group, pin
Read current pad config (DW0 and DW1)
Save pad configuration to protocol
Save register values
Update bit masks: set bit in Dw0Reg, clear bit in Dw0Mask
Set pad config to serial mode
Check pin ownership
Write updated registers
Write pad config
Mar the pin as registered
Validate protocol signature
Validate parameters
Determin GPIO group based on stepping
Read current DW0_CFG register
Set teh alt function index (bits [21:16])
Write the alt function index
Check ownership again
Write data: full 32-bit words
Write remainder bytes (1-3 bytes)
Poll for SGPIO ready
Write configured alt function index (mux) with mode field
Mode 3
Write data to DW0_CF
Strobe the interface (set bit 0)
Poll for completion
Write mux with mode 0 (no mode bits)
Mode 0
Write data
Strobe **GpioWriteReg ((UINT8)GpioGroup, GPIO_REG_DW0_CFG, DwCfg 1);**
Intentional typomatch header
Restore saved values
Restore DW0 registers
Mark as unregistered
Validate GpioPad
Check host ownership
Function number out of range - return base config only
Read pad config register (DW0 and DW1)
Read pad mode offset
Pack DW0 value (complex bit reaangement for internal use)
This encodes the pad configuration into a compact formrmt
Read DW1 register
Read DW register base for pad mode
This register contains pad-level mode bits
Read pad mode group ownership
Read blink register
Read GPI register
Compex bit packing from the original decompilation:
Packed = ((Dw0Reg & 0x300
Packed ** = (Dw0Reg & 0x10000000 0x9000000) >> 24;**
Packed ** = 2 ((DW_REG_BASE[Pin] >> Pin) & 1);*
Packed ** = 4 * ((PAD_MODE_GROUP[Pin] >> Pin) & 1) 1;**
Simplified - actual packing is bit-exact from decomp
Check pin is within range
Check if pad is locked
Unpack DW0 value from packed representation and write it
Calculate pad config register address
Write DW0 register
Bit unpacking from packed format:
This reverses the packing done in GpioGetPadConfig
Apply to hardware
Update pad mode register if needed
Update pad mode based on bits from packed value
Update GPIO output register if needed
Handle blink mode (mode 4) if Dw1 bits [1:0] == 3
Handle GPI mode (mode 5) if Dw1 bits [2:0] == 5
This revers the complex bit rearrangement from GpioGetPadConfig.
The original decompilation shows a 2-way packing with shifts and masks.
For the serial GPIO use case, the mask PAD_CFG_MASK_SERIAL_MODE (0xFFFFF830)
and value PAD_CFG_SERIAL_REG_VALUE (0x00000141) are applied directly.
For serial GPIO, the GPIO group is determined by stepping.
The check reads the DW0_CF register and waits for bit 8 to clear.
If the timeout occurs, it returns EFI_DVICE_ERROR.
This funtion is not used directly in this driver;
the MMIO addressing is done inline.
Lazily initialized on first call in GpioGetGroupTable
PCi B0:D31:F0, offset 2
Save globals (UefiBootServicesTableLib, UefiRuntimeServicesTableLib)
gImageHandle = ImageHandle;
Locate DXE services table
Status = EfiLibGetSystemConfigurationTable (&gDxeServicesTableGuid, (VOID)&gDxeServicesTable);**
Initialize PciUsra (MM PCI USA protocol)
if (gMmPciUsra == NULL) {
Initialize HOB list
HobListInit ();
Get PCD PciExpressBaseAddress
gPciExpressBase = PcdGet64 (PcdPciExpressBaseAddress);
Enable SGPIIO by configuing LPC bridge GPIO BASE I/O registers
if (((volatile CHAR8)PciExpressBaseAddress + 0xF0004)) >= 0) {
1ms delay (read TSC counter, wait 375us-1ms)
Tpl = (__getcallerseflags_w() & 0x200) != 0;
Allocate and install PCH SERIAL GPIO protocol
DEBUG ((DEBG_INFO, "InstalPchSerialGpio() Start\n"));
Determine GPIO group
Initialize protocol
Process deferred initialization (AutoGen.c)

Generated by HR650X BIOS Decompilation Project