# PiSmmCpuDxeSmm

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **_ModuleEntryPoint** |  |
|  | **SmmInit** |  |
|  | **SmiHandlerDispatch** |  |
|  | **SmmRestoreCpu** |  |
|  | **InitMp** |  |
|  | **ProgramRegisterTable** |  |
|  | **InitPaging** |  |
|  | **DebugPrint** |  |
|  | **AssertBreak** |  |
|  | **PciExpressAddress** |  |
|  | **AcquireSpinLock** |  |
|  | **ReleaseSpinLock** |  |
|  | **SmiHandlerFeatureMsr** |  |
|  | **SendSmiIpi** |  |
|  | **StartupAP** |  |
|  | **GetCpuIndex** |  |
|  | **IsCpuSandyBridge** |  |
|  | **IsCpuKnightsLanding** |  |
|  | **IsCpuIvyTown** |  |
|  | **CpuDeadLoop** |  |
| Global | **data initialized at module entry** |  |
| EFI_HANDLE | **gImageHandle  = NULL;    // 0x108F0** |  |
| 0x10698 | **- SystemTable alias** |  |
| 0x108E8 | **UINT64             gSmst         = NULL;    // 0x10900 - SMM System Table (gSmst)** |  |
| 0x10908 | **UINT64             gPciExpressBase = 0;     // 0x10910 - PCIe config base address** |  |
| 0x10920 | **//** |  |
| SMM | **S3 Resume State - pointer to S3 resume structure in SMRAM** |  |
| Checked | **by SmmRestoreCpu() at 0x1C3C for:** |  |
| Signature | **"SMM_S_32" (0x32335F33534D4D53) -> use AsmDisablePaging64** |  |
| Signature | **"SMM_S_64" (0x34365F33534D4D53) -> use SwitchStack** |  |
| SMM_S3_RESUME_STATE | ***mSmmS3ResumeState = NULL;  // 0x10690** |  |
| CPU | **configuration** |  |
| UINT32 | **mNumberOfCpus           = 0;  // 0x118A4** |  |
| 0x118A0 | **UINT32  mCpusExiting            = 0;  // 0x11870 - APs remaining to finish init** |  |
| 0x118C8 | **UINT64  mStartupRoutine         = 0;  // 0x11880** |  |
| 0x11878 | **UINT64  mGdtBuffer              = 0;  // 0x11898** |  |
| 0x118A8 | **UINT64  mGdtrProfile            = 0;  // 0x11888** |  |
| 0x11890 | **UINT64  mPreSmmInitRegisterTable = 0; // 0x118B0** |  |
| 0x118B8 | **UINT64  mGdtForAp               = 0;  // 0x118C0** |  |
| 0x11910 | **UINT8   mApStartPhase           = 0;  // 0x11918** |  |
| UINT64 | **mGdtForApAlloc   = 0;  // 0x10890** |  |
| 0x10898 | **UINT64  mExcptHandlerAlloc = 0; // 0x108A0** |  |
| MSR | **Spin Locks** |  |
| UINT64 | **mMsrSpinLocks    = 0;  // 0x108A8 - base address** |  |
| 0x108B0 | **UINT64  mMsrSpinLockMax  = 0;  // 0x105F0** |  |
| CPU | **enabling bitmap** |  |
| UINT64 | **mCpuEnabledBitmap = 0; // 0x108B8** |  |
| State | **flags** |  |
| UINT8 | **mGdtIdtReady      = 0;  // 0x10888** |  |
| 0x10889 | **UINT8   mSmrrConfigured   = 0;  // 0x118E9** |  |
| Exception | **handler base/length** |  |
| UINT64 | **mExceptionHandlerBase = 0; // 0x10970** |  |
| SMM | **CPU private data array (off_10378 at 0x10378)** |  |
| An | **11-entry array of pointers to per-CPU SMM data:** |  |
| volatile | **UINT64  *gSmmCpuPrivate = (volatile UINT64 *)0x10378;** |  |
| 0xB90 | **SmmEntryPointSaveHandles(ImageHandle);  // sub_C4C** |  |
| qword_10788 | **= 0x8000000000000001** |  |
| Lock | **acquired - we are the first to init** |  |
| sub_2390 | **if (gStatus >= 0 || gStatus < 0) {    // always true after init** |  |
| preserve | **status** |  |
| Debug | **asserts for build info** |  |
| 0x2390 | **- Entry** |  |
| Extensive | **initialization sequence spanning SmmFeatures.c** |  |
| Step | **1: Initialize SMM protocol interfaces** |  |
| Locate | **SMM System Table (gSmst) at qword_10900** |  |
| Register | **communication handler** |  |
| Set | **up SMI entry/exit** |  |
| Step | **2: CPU detection** |  |
| CPUID | **to determine CPU family (SNB/HSW/SKX/KNL/IVT)** |  |
| Step | **3: Page table initialization** |  |
| Step | **4: Long mode setup** |  |
| Step | **5: MP data initialization** |  |
| Step | **6: SMM features initialization** |  |
| Registers | **SmiHandlerDispatch() as SwSmiHandler** |  |
| Registers | **SmiHandlerFeatureMsr() for feature MSR access** |  |
| Step | **7: MP wake and startup** |  |
| Start | **APs with StartupRoutine** |  |
| Each | **AP calls ProgramRegisterTable() for its register table entries** |  |
| Wait | **for all APs via mCpusExiting counter** |  |
| 0x3BD0 | **UINT64  MsrValue;** |  |
| Check | **CPU model and dispatch to correct MSR handling** |  |
| Not | **SNB/HSW/SKX - try other models** |  |
| sub_A0DC | **if (ReadWrite == 0) {** |  |
| Read | **0x4107C** |  |
| Write | **to 0x41050/0x41054** |  |
| IVT | **MSR handling at 0x4115x - 0x4117x range** |  |
| 0x1C3C | **SMM_S3_RESUME_STATE  *S3State;** |  |
| qword_10690 | **if (S3State == NULL) {** |  |
| Save | **IDT, set up page tables, init exception handler** |  |
| sub_B45C | **if (EFI_ERROR(Status)) {** |  |
| Initialize | **interrupt state for APs** |  |
| sub_524C | **LaunchS3Resume();      // sub_1A90** |  |
| Program | **register table for BSP** |  |
| sub_4F70 | **// Set up return state** |  |
| Set | **return function** |  |
| GDT | **pointer** |  |
| Return | **function** |  |
| Start | **APs with SIPI** |  |
| Determine | **resume method based on signature** |  |
| sub_8384 | **}** |  |
| 0x2110 | **ACPI_CPU_DATA  *AcpiCpuData;** |  |
| Get | **ACPI CPU data via protocol** |  |
| sub_8AA8 | **// Allocate and copy MTRR table** |  |
| sub_9C8C | **CopyMem(mMtrrTable, *(AcpiCpuData->MtrrTable), 608);** |  |
| Allocate | **and copy GDTR profile** |  |
| Allocate | **and copy IDTR profile** |  |
| Allocate | **and copy PreSmmInitRegisterTable (24 bytes per CPU)** |  |
| Allocate | **and copy RegisterTable (24 bytes per CPU)** |  |
| Allocate | **combined GDT/IDT/Exception handler region** |  |
| 0x4F70 | **// Entry processing:** |  |
| Count | **== 1: BitField read -> modify -> write** |  |
| Read | **MSR, mask StartBit..StartBit+BitsLength-1, write Value** |  |
| Uses | **BitFieldRead64/Write64 then CR writes (sub_410=cr0, sub_420=cr3, etc.)** |  |
| Count | **== 3: Cache maintain (wbinvd or just clean)** |  |
| Count | **== 0 && BitsLength < 0x40:** |  |
| Look | **up MSR in mMsrSpinLocks, acquire lock, read/modify/write MSR, release** |  |
| Count | **== 0: direct write via __writemsr()** |  |
| 0x314C | **// 1. Get SMM Access2 Protocol** |  |
| 0x9AA4 | **// 1. Check if Format is NULL -> ASSERT** |  |
| 0x9B78 | **// AsciiSPrint("ASSERT [%a] %a(%d): %a\n", ...)** |  |
| Then | **break via SerialPortWrite** |  |
| 0x9BCC | **if ((Address & ~0xFFFFFFF) != 0) {** |  |
| 0xA0DC | **// Check if already acquired via IsSpinLockAcquired** |  |
| If | **not:** |  |
| StartTime | **= ReadTsc()** |  |
| Timeout | **= 10000000 * gTimerPeriod / 0xF4240** |  |
| while | **not acquired:** |  |
| if | **(elapsed >= Timeout) ASSERT** |  |
| 0xA20C | **// ASSERT(SpinLock != NULL)** |  |
| 0x4344 | **// Same dispatch pattern as SmiHandlerDispatch but** |  |
| specifically | **handles MSR read/write at:** |  |
| 0x41058 | **(KNL read)** |  |
| 0x4107C | **(KNL status)** |  |
| 0xA598 | **// if (GetApicMode() == xAPIC) {** |  |
| Save | **eflags, cli** |  |
| Write | **APIC ICR register via memory-mapped APIC** |  |
| Wait | **for ICR to be accepted** |  |
| x2APIC | **mode: use MSR 0x830** |  |
| 0xA78C | **// ASSERT(StartupRoutine < 0x100000)** |  |
| Send | **INIT IPI (0xC4500 = delivery + INIT)** |  |
| Delay | **10ms** |  |
| Send | **SIPI with startup page** |  |
| Delay | **200us** |  |
| Send | **SIPI again** |  |
| 0xA6C4 | **// if (GetApicMode() != 1) {** |  |
| return | **GetApicId();  // x2APIC: APIC ID == CPU index** |  |
| CPUID | **leaf 0xB: get x2APIC ID** |  |
| If | **leaf 0xB available:** |  |
| CPU | **Feature Checks** |  |
| 0x3694 | **INT32  CpuVersion;** |  |
| sub_470 | **CpuVersion &= 0xFFF0FF0;** |  |

---
*Generated by HR650X BIOS Decompilation Project*