# RegAccessPeim - Register Access PEIM

## Module Information

| Field | Value |
|-------|-------|
| **Module Name** | RegAccessPeim.efi |
| **Index** | 0368 |
| **Architecture** | IA32 (32-bit) |
| **Base Address** | 0xFFDAE9EC |
| **Image Size** | 0x2180 (8,576 bytes) |
| **MD5** | 21b4333fffdb77a75b6ac76d03381564 |
| **SHA256** | 06a6b9c070f5f34999d24c8c98445461cbdd1808d17715adaf3d12fd99313e47 |
| **Source** | CpRcPkg/Universal/RegAccess/Pei/RegAccess.c |
| **PDB** | Build/HR6N0XMLK/DEBUG_VS2015/IA32/.../RegAccessPeim.pdb |
| **Entry Point** | 0xFFDAED01 (RegAccessEntryPoint) |

## Overview

This PEIM provides register read/write/modify services during the PEI (Pre-EFI Initialization) phase. It handles access to various CPU and platform registers across multiple sockets, IIO (Integrated IO) complexes, and functional blocks (CHA, PCU, Ubox, M2MEM, KTI, etc.).

The module registers a **PEI REG_ACCESS PPI** that exposes four operations:
- Read Register
- Write Register
- Read-Modify (AND/OR mask)
- Get Config Space (MMIO base address)

Each operation dispatches through a function pointer table indexed by a box type field extracted from the descriptor.

## Architecture

### Call Flow

```
RegAccessEntryPoint()
  |-- GetPeiServicesTablePointer()        <- via IDT-based lookup
  |-- PcdGetProtocol()                    <- Get PCD PPI
  |-- InstallPpi()                        <- Register RegAccess PPI
  |-- DebugAssertReport()                 <- Error handling

RegAccessReadRegister() / RegAccessWriteRegister() / RegAccessReadModify()
  |-- dispatch via function tables
  |-- RegAccessReadByType0 / RegAccessWriteByType0 / RegAccessReadModifyByType0
  |   |-- RegAccessGetCfgAddress()        <- Get MMIO base from PCD
  |   |-- IoMemRead / IoMemWrite          <- Aligned memory access
  |
  |-- RegAccessReadMulti / RegAccessWriteMulti
  |   |-- RegAccessGetCfgAddress()        <- Get MMIO base
  |   |-- RegAccessValidateRange()        <- Validate alignment & bounds
  |   |-- IoMemRead / IoMemWrite (loop)   <- Multi-element access

RegAccessTranslateFull()
  |-- TranslateAddressWalk()
  |   |-- CpuTypeToTableIndex()           <- Level 1: Socket/CpuType mapping
  |   |-- CpuTypeToDeviceIndex()          <- Level 2: Device number mapping
  |   |-- FuncBlockToIndex()              <- Level 3: Function block mapping
  |-- RegAccessLookupTablePointer()       <- Get PCD table address
```

### Function Table Dispatch

The module uses 4 dispatch tables in .rdata:

| Table | Address | Indexed By | Functions |
|-------|---------|------------|-----------|
| gRegAccessReadDispatchTable | 0xFFDB05B0 | box type (bits 8-11 of ExtInfo) | RegAccessReadByType0, RegAccessReadMulti |
| gRegAccessWriteDispatchTable | 0xFFDB05BC | box type | RegAccessWriteByType0, RegAccessWriteMulti |
| gRegAccessReadModifyDispatchTable | 0xFFDB05C8 | box type | RegAccessReadModifyByType0 |
| gRegAccessConfigDispatchTable | 0xFFDB05D4 | box type | RegAccessGetCfgAddress |

### Function Roster (44 functions)

| Original Name | New Name | Address | Size | Description |
|---------------|----------|---------|------|-------------|
| sub_FFDAEC4C | RegAccessMemSet | 0xFFDAEC4C | 0x15 | memset wrapper |
| sub_FFDAEC6C | RegAccessMemMove | 0xFFDAEC6C | 0x3F | memmove with overlap handling |
| sub_FFDAECCC | RegAccessFill64 | 0xFFDAECCC | 0x1F | Fill array with 64-bit values |
| sub_FFDAECEC | RegAccessMemSet32 | 0xFFDAECEC | 0x15 | memset32 wrapper |
| _ModuleEntryPoint | RegAccessEntryPoint | 0xFFDAED01 | 0x4B | PEIM entry point |
| sub_FFDAED4C | RegAccessReadRegister | 0xFFDAED4C | 0x17 | Dispatch: Read Register |
| sub_FFDAED63 | RegAccessWriteRegister | 0xFFDAED63 | 0x17 | Dispatch: Write Register |
| sub_FFDAED7A | RegAccessReadModify | 0xFFDAED7A | 0x1C | Dispatch: Read-Modify-Write |
| sub_FFDAED96 | RegAccessGetConfigSpace | 0xFFDAED96 | 0x22 | Dispatch: Get Config Space |
| sub_FFDAEDB8 | GetPeiServicesPpi | 0xFFDAEDB8 | 0x31 | Get PPI via PeiServices |
| sub_FFDAEDE9 | DebugAssertReport | 0xFFDAEDE9 | 0x2A | Report assert/debug message |
| sub_FFDAEE13 | DebugPrintWorker | 0xFFDAEE13 | 0x1E | Debug print via PPI |
| sub_FFDAEE31 | IsDebugEnabled | 0xFFDAEE31 | 0x03 | Always returns TRUE |
| sub_FFDAEE34 | BoolCheck | 0xFFDAEE34 | 0x09 | Boolean check (a != 0) |
| sub_FFDAEE3D | IoMemRead | 0xFFDAEE3D | 0x8A | Aligned IO memory read (1/2/8 bytes) |
| sub_FFDAEEC7 | IoMemWrite | 0xFFDAEEC7 | 0x82 | Aligned IO memory write (1/2/4+4 bytes) |
| sub_FFDAEF49 | BitFieldMerge | 0xFFDAEF49 | 0x8D | Bitwise merge with AND/OR masks |
| sub_FFDAEFD6 | RegAccessGetCfgThunk | 0xFFDAEFD6 | 0x05 | Thunk to TranslateFull + IoMemRead |
| sub_FFDAEFDB | RegAccessReadCfgThunk | 0xFFDAEFDB | 0x37 | Translate + IoMemRead config space |
| sub_FFDAF012 | RegAccessWriteCfgThunk | 0xFFDAF012 | 0x3D | Translate + IoMemWrite config space |
| sub_FFDAF04F | RegAccessReadModifyThunk | 0xFFDAF04F | 0x80 | Translate + RMW via AND/OR |
| sub_FFDAF0CF | RegAccessGetCfgAddress | 0xFFDAF0CF | 0x1E | Get MMIO address from PCD |
| sub_FFDAF0ED | RegAccessReadByType0 | 0xFFDAF0ED | 0x34 | Read register (type 0 path) |
| sub_FFDAF121 | RegAccessValidateRange | 0xFFDAF121 | 0xB7 | Validate range/alignment for access |
| sub_FFDAF1D8 | RegAccessReadMulti | 0xFFDAF1D8 | 0x99 | Multi-element register read |
| sub_FFDAF271 | RegAccessWriteByType0 | 0xFFDAF271 | 0x39 | Write register (type 0 path) |
| sub_FFDAF2AA | RegAccessWriteMulti | 0xFFDAF2AA | 0x99 | Multi-element register write |
| sub_FFDAF343 | RegAccessReadModifyByType0 | 0xFFDAF343 | 0x53 | Read-modify-write (type 0 path) |
| sub_FFDAF396 | GetPeiServicesTablePointer | 0xFFDAF396 | 0x32 | Get PeiServices via IDT |
| sub_FFDAF3C8 | GetDebugErrorLevel | 0xFFDAF3C8 | 0x4F | Read debug level from CMOS 0x4A |
| sub_FFDAF417 | InternalLShift64 | 0xFFDAF417 | 0x42 | 64-bit left shift wrappper |
| sub_FFDAF459 | InternalRShift64 | 0xFFDAF459 | 0x42 | 64-bit right shift wrapper |
| sub_FFDAF49B | InternalReadIdtr | 0xFFDAF49B | 0x23 | Read IDTR (sidt instruction) |
| sub_FFDAF4BE | PcdInitRegAccessData | 0xFFDAF4BE | 0x9B | PCD data buffer init |
| sub_FFDAF559 | RegAccessLookupTablePointer | 0xFFDAF559 | 0x17E | PCD table address lookup |
| sub_FFDAF6D7 | PcdGetProtocol | 0xFFDAF6D7 | 0x58 | Locate PCD PPI protocol |
| sub_FFDAF72F | PcdGetPtr | 0xFFDAF72F | 0x0F | PCD GetPtr wrapper |
| sub_FFDAF73E | PcdGetSize | 0xFFDAF73E | 0x0F | PCD GetSize wrapper |
| sub_FFDAF74D | RegAccessTranslateFull | 0xFFDAF74D | 0x10D | Full address translation with caching |
| sub_FFDAF85A | TranslateAddressWalk | 0xFFDAF85A | 0x98 | 3-level page table walk |
| sub_FFDAF8F2 | CpuDeadLoopEx | 0xFFDAF8F2 | 0x6C | CpuDeadLoop with assert |
| sub_FFDAF95E | CpuTypeToTableIndex | 0xFFDAF95E | 0x1C8 | Socket/box-type to table index |
| sub_FFDAFB26 | CpuTypeToDeviceIndex | 0xFFDAFB26 | 0x359 | CPU topology to device index |
| sub_FFDAFED6 | FuncBlockToIndex | 0xFFDAFED6 | 0x1F5 | Function block to table offset |
| sub_FFDB010B | RegAccessStripHighBits | 0xFFDB010B | 0x0A | Strip high address bits (return & 0xFFFF0000) |

## Global Data

| Address | Name | Size | Description |
|---------|------|------|-------------|
| 0xFFDB05B0 | funcs_FFDAED70 | 12 | Read dispatch table (3 entries) |
| 0xFFDB05BC | funcs_FFDAED59 | 12 | Write dispatch table |
| 0xFFDB05C8 | funcs_FFDAED8B | 12 | ReadModify dispatch table |
| 0xFFDB05D4 | funcs_FFDAEDA9 | 12 | GetConfig dispatch table |
| 0xFFDB05E0 | byte_FFDB05E0 | 12 | Access width per box type |
| 0xFFDB05EC | byte_FFDB05EC | 12 | Element stride per box type |
| 0xFFDB090C | byte_FFDB090C | 56+ | Functional block to device tables (168-byte rows) |
| 0xFFDB09B4 | byte_FFDB09B4 | 5 | KTI instance to device mapping |
| 0xFFDB09BC | unk_FFDB09BC | - | RegAccess PPI GUID data |
| 0xFFDB0A08 | dword_FFDB0A08 | - | PCD config space (".data") |

## Strings

All 55 strings include path references (build paths), format strings for CPU/IO box assertions, and assert condition strings. Key platform box types identified:
- CHA (Caching & Home Agent)
- CHABC (CHA Broadcast)
- PCU (Power Control Unit)
- VCU (Voltage Control Unit)
- KTI (KTI/UPI link)
- M2MEM (Memory 2 Memory)
- IIO_PCIE, IIO_CB, IIO_VTD, IIO_DFX (Integrated IO sub-types)
- UBOX (Uncore Box)
- FPGA

## Error Status Values Used

| Value | Meaning |
|-------|---------|
| 0x80000002 | EFI_UNSUPPORTED |
| 0x80000003 | EFI_INVALID_PARAMETER (alignment) |
| 0x80000005 | EFI_ALIGNMENT_ERROR |
| 0x8000000C | EFI_INVALID_PARAMETER |
| 0x80000015 | EFI_ALREADY_STARTED |

## Dependencies (PPIs used)

- **PCD PPI** (gEfiPeiPcdPpiGuid) - for platform configuration data
- **PeiServices** (via IDT table pointer) - for debug output
