# 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*