/** @file
PiSmmCpuDxeSmm.h -- Header for PiSmmCpuDxeSmm
Copyright (c) HR650X BIOS Decompilation Project
**/
#ifndef __PISMMCPUDXESMM_H__
#define __PISMMCPUDXESMM_H__
#include "../uefi_headers/Uefi.h"
//
// Function Prototypes
//
EFI_STATUS
EFIAPI
_ModuleEntryPoint(
VOID
);
EFI_STATUS
EFIAPI
SmmInit(
VOID
);
EFI_STATUS
EFIAPI
SmiHandlerDispatch(
VOID
);
EFI_STATUS
EFIAPI
SmmRestoreCpu(
VOID
);
EFI_STATUS
EFIAPI
InitMp(
VOID
);
EFI_STATUS
EFIAPI
ProgramRegisterTable(
VOID
);
EFI_STATUS
EFIAPI
InitPaging(
VOID
);
EFI_STATUS
EFIAPI
DebugPrint(
VOID
);
EFI_STATUS
EFIAPI
AssertBreak(
VOID
);
EFI_STATUS
EFIAPI
PciExpressAddress(
VOID
);
EFI_STATUS
EFIAPI
AcquireSpinLock(
VOID
);
EFI_STATUS
EFIAPI
ReleaseSpinLock(
VOID
);
EFI_STATUS
EFIAPI
SmiHandlerFeatureMsr(
VOID
);
EFI_STATUS
EFIAPI
SendSmiIpi(
VOID
);
EFI_STATUS
EFIAPI
StartupAP(
VOID
);
EFI_STATUS
EFIAPI
GetCpuIndex(
VOID
);
EFI_STATUS
EFIAPI
IsCpuSandyBridge(
VOID
);
EFI_STATUS
EFIAPI
IsCpuKnightsLanding(
VOID
);
EFI_STATUS
EFIAPI
IsCpuIvyTown(
VOID
);
EFI_STATUS
EFIAPI
CpuDeadLoop(
VOID
);
EFI_STATUS
EFIAPI
data initialized at module entry(
VOID
);
EFI_STATUS
EFIAPI
gImageHandle = NULL; // 0x108F0(
VOID
);
EFI_STATUS
EFIAPI
- SystemTable alias(
VOID
);
EFI_STATUS
EFIAPI
UINT64 gSmst = NULL; // 0x10900 - SMM System Table (gSmst)(
VOID
);
EFI_STATUS
EFIAPI
UINT64 gPciExpressBase = 0; // 0x10910 - PCIe config base address(
VOID
);
EFI_STATUS
EFIAPI
//(
VOID
);
EFI_STATUS
EFIAPI
S3 Resume State - pointer to S3 resume structure in SMRAM(
VOID
);
EFI_STATUS
EFIAPI
by SmmRestoreCpu() at 0x1C3C for:(
VOID
);
EFI_STATUS
EFIAPI
"SMM_S_32" (0x32335F33534D4D53) -> use AsmDisablePaging64(
VOID
);
EFI_STATUS
EFIAPI
"SMM_S_64" (0x34365F33534D4D53) -> use SwitchStack(
VOID
);
EFI_STATUS
EFIAPI
*mSmmS3ResumeState = NULL; // 0x10690(
VOID
);
EFI_STATUS
EFIAPI
configuration(
VOID
);
EFI_STATUS
EFIAPI
mNumberOfCpus = 0; // 0x118A4(
VOID
);
EFI_STATUS
EFIAPI
UINT32 mCpusExiting = 0; // 0x11870 - APs remaining to finish init(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mStartupRoutine = 0; // 0x11880(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mGdtBuffer = 0; // 0x11898(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mGdtrProfile = 0; // 0x11888(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mPreSmmInitRegisterTable = 0; // 0x118B0(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mGdtForAp = 0; // 0x118C0(
VOID
);
EFI_STATUS
EFIAPI
UINT8 mApStartPhase = 0; // 0x11918(
VOID
);
EFI_STATUS
EFIAPI
mGdtForApAlloc = 0; // 0x10890(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mExcptHandlerAlloc = 0; // 0x108A0(
VOID
);
EFI_STATUS
EFIAPI
Spin Locks(
VOID
);
EFI_STATUS
EFIAPI
mMsrSpinLocks = 0; // 0x108A8 - base address(
VOID
);
EFI_STATUS
EFIAPI
UINT64 mMsrSpinLockMax = 0; // 0x105F0(
VOID
);
EFI_STATUS
EFIAPI
enabling bitmap(
VOID
);
EFI_STATUS
EFIAPI
mCpuEnabledBitmap = 0; // 0x108B8(
VOID
);
EFI_STATUS
EFIAPI
flags(
VOID
);
EFI_STATUS
EFIAPI
mGdtIdtReady = 0; // 0x10888(
VOID
);
EFI_STATUS
EFIAPI
UINT8 mSmrrConfigured = 0; // 0x118E9(
VOID
);
EFI_STATUS
EFIAPI
handler base/length(
VOID
);
EFI_STATUS
EFIAPI
mExceptionHandlerBase = 0; // 0x10970(
VOID
);
EFI_STATUS
EFIAPI
CPU private data array (off_10378 at 0x10378)(
VOID
);
EFI_STATUS
EFIAPI
11-entry array of pointers to per-CPU SMM data:(
VOID
);
EFI_STATUS
EFIAPI
UINT64 *gSmmCpuPrivate = (volatile UINT64 *)0x10378;(
VOID
);
EFI_STATUS
EFIAPI
SmmEntryPointSaveHandles(ImageHandle); // sub_C4C(
VOID
);
EFI_STATUS
EFIAPI
= 0x8000000000000001(
VOID
);
EFI_STATUS
EFIAPI
acquired - we are the first to init(
VOID
);
EFI_STATUS
EFIAPI
if (gStatus >= 0 || gStatus < 0) { // always true after init(
VOID
);
EFI_STATUS
EFIAPI
status(
VOID
);
EFI_STATUS
EFIAPI
asserts for build info(
VOID
);
EFI_STATUS
EFIAPI
- Entry(
VOID
);
EFI_STATUS
EFIAPI
initialization sequence spanning SmmFeatures.c(
VOID
);
EFI_STATUS
EFIAPI
1: Initialize SMM protocol interfaces(
VOID
);
EFI_STATUS
EFIAPI
SMM System Table (gSmst) at qword_10900(
VOID
);
EFI_STATUS
EFIAPI
communication handler(
VOID
);
EFI_STATUS
EFIAPI
up SMI entry/exit(
VOID
);
EFI_STATUS
EFIAPI
2: CPU detection(
VOID
);
EFI_STATUS
EFIAPI
to determine CPU family (SNB/HSW/SKX/KNL/IVT)(
VOID
);
EFI_STATUS
EFIAPI
3: Page table initialization(
VOID
);
EFI_STATUS
EFIAPI
4: Long mode setup(
VOID
);
EFI_STATUS
EFIAPI
5: MP data initialization(
VOID
);
EFI_STATUS
EFIAPI
6: SMM features initialization(
VOID
);
EFI_STATUS
EFIAPI
SmiHandlerDispatch() as SwSmiHandler(
VOID
);
EFI_STATUS
EFIAPI
SmiHandlerFeatureMsr() for feature MSR access(
VOID
);
EFI_STATUS
EFIAPI
7: MP wake and startup(
VOID
);
EFI_STATUS
EFIAPI
APs with StartupRoutine(
VOID
);
EFI_STATUS
EFIAPI
AP calls ProgramRegisterTable() for its register table entries(
VOID
);
EFI_STATUS
EFIAPI
for all APs via mCpusExiting counter(
VOID
);
EFI_STATUS
EFIAPI
UINT64 MsrValue;(
VOID
);
EFI_STATUS
EFIAPI
CPU model and dispatch to correct MSR handling(
VOID
);
EFI_STATUS
EFIAPI
SNB/HSW/SKX - try other models(
VOID
);
EFI_STATUS
EFIAPI
if (ReadWrite == 0) {(
VOID
);
EFI_STATUS
EFIAPI
0x4107C(
VOID
);
EFI_STATUS
EFIAPI
to 0x41050/0x41054(
VOID
);
EFI_STATUS
EFIAPI
MSR handling at 0x4115x - 0x4117x range(
VOID
);
EFI_STATUS
EFIAPI
SMM_S3_RESUME_STATE *S3State;(
VOID
);
EFI_STATUS
EFIAPI
if (S3State == NULL) {(
VOID
);
EFI_STATUS
EFIAPI
IDT, set up page tables, init exception handler(
VOID
);
EFI_STATUS
EFIAPI
if (EFI_ERROR(Status)) {(
VOID
);
EFI_STATUS
EFIAPI
interrupt state for APs(
VOID
);
EFI_STATUS
EFIAPI
LaunchS3Resume(); // sub_1A90(
VOID
);
EFI_STATUS
EFIAPI
register table for BSP(
VOID
);
EFI_STATUS
EFIAPI
// Set up return state(
VOID
);
EFI_STATUS
EFIAPI
return function(
VOID
);
EFI_STATUS
EFIAPI
pointer(
VOID
);
EFI_STATUS
EFIAPI
function(
VOID
);
EFI_STATUS
EFIAPI
APs with SIPI(
VOID
);
EFI_STATUS
EFIAPI
resume method based on signature(
VOID
);
EFI_STATUS
EFIAPI
}(
VOID
);
EFI_STATUS
EFIAPI
ACPI_CPU_DATA *AcpiCpuData;(
VOID
);
EFI_STATUS
EFIAPI
ACPI CPU data via protocol(
VOID
);
EFI_STATUS
EFIAPI
// Allocate and copy MTRR table(
VOID
);
EFI_STATUS
EFIAPI
CopyMem(mMtrrTable, *(AcpiCpuData->MtrrTable), 608);(
VOID
);
EFI_STATUS
EFIAPI
and copy GDTR profile(
VOID
);
EFI_STATUS
EFIAPI
and copy IDTR profile(
VOID
);
EFI_STATUS
EFIAPI
and copy PreSmmInitRegisterTable (24 bytes per CPU)(
VOID
);
EFI_STATUS
EFIAPI
and copy RegisterTable (24 bytes per CPU)(
VOID
);
EFI_STATUS
EFIAPI
combined GDT/IDT/Exception handler region(
VOID
);
EFI_STATUS
EFIAPI
// Entry processing:(
VOID
);
EFI_STATUS
EFIAPI
== 1: BitField read -> modify -> write(
VOID
);
EFI_STATUS
EFIAPI
MSR, mask StartBit..StartBit+BitsLength-1, write Value(
VOID
);
EFI_STATUS
EFIAPI
BitFieldRead64/Write64 then CR writes (sub_410=cr0, sub_420=cr3, etc.)(
VOID
);
EFI_STATUS
EFIAPI
== 3: Cache maintain (wbinvd or just clean)(
VOID
);
EFI_STATUS
EFIAPI
== 0 && BitsLength < 0x40:(
VOID
);
EFI_STATUS
EFIAPI
up MSR in mMsrSpinLocks, acquire lock, read/modify/write MSR, release(
VOID
);
EFI_STATUS
EFIAPI
== 0: direct write via __writemsr()(
VOID
);
EFI_STATUS
EFIAPI
// 1. Get SMM Access2 Protocol(
VOID
);
EFI_STATUS
EFIAPI
// 1. Check if Format is NULL -> ASSERT(
VOID
);
EFI_STATUS
EFIAPI
// AsciiSPrint("ASSERT [%a] %a(%d): %a\n", ...)(
VOID
);
EFI_STATUS
EFIAPI
break via SerialPortWrite(
VOID
);
EFI_STATUS
EFIAPI
if ((Address & ~0xFFFFFFF) != 0) {(
VOID
);
EFI_STATUS
EFIAPI
// Check if already acquired via IsSpinLockAcquired(
VOID
);
EFI_STATUS
EFIAPI
not:(
VOID
);
EFI_STATUS
EFIAPI
= ReadTsc()(
VOID
);
EFI_STATUS
EFIAPI
= 10000000 * gTimerPeriod / 0xF4240(
VOID
);
EFI_STATUS
EFIAPI
not acquired:(
VOID
);
EFI_STATUS
EFIAPI
(elapsed >= Timeout) ASSERT(
VOID
);
EFI_STATUS
EFIAPI
// ASSERT(SpinLock != NULL)(
VOID
);
EFI_STATUS
EFIAPI
// Same dispatch pattern as SmiHandlerDispatch but(
VOID
);
EFI_STATUS
EFIAPI
handles MSR read/write at:(
VOID
);
EFI_STATUS
EFIAPI
(KNL read)(
VOID
);
EFI_STATUS
EFIAPI
(KNL status)(
VOID
);
EFI_STATUS
EFIAPI
// if (GetApicMode() == xAPIC) {(
VOID
);
EFI_STATUS
EFIAPI
eflags, cli(
VOID
);
EFI_STATUS
EFIAPI
APIC ICR register via memory-mapped APIC(
VOID
);
EFI_STATUS
EFIAPI
for ICR to be accepted(
VOID
);
EFI_STATUS
EFIAPI
mode: use MSR 0x830(
VOID
);
EFI_STATUS
EFIAPI
// ASSERT(StartupRoutine < 0x100000)(
VOID
);
EFI_STATUS
EFIAPI
INIT IPI (0xC4500 = delivery + INIT)(
VOID
);
EFI_STATUS
EFIAPI
10ms(
VOID
);
EFI_STATUS
EFIAPI
SIPI with startup page(
VOID
);
EFI_STATUS
EFIAPI
200us(
VOID
);
EFI_STATUS
EFIAPI
SIPI again(
VOID
);
EFI_STATUS
EFIAPI
// if (GetApicMode() != 1) {(
VOID
);
EFI_STATUS
EFIAPI
GetApicId(); // x2APIC: APIC ID == CPU index(
VOID
);
EFI_STATUS
EFIAPI
leaf 0xB: get x2APIC ID(
VOID
);
EFI_STATUS
EFIAPI
leaf 0xB available:(
VOID
);
EFI_STATUS
EFIAPI
Feature Checks(
VOID
);
EFI_STATUS
EFIAPI
INT32 CpuVersion;(
VOID
);
EFI_STATUS
EFIAPI
CpuVersion &= 0xFFF0FF0;(
VOID
);
#endif /* __PISMMCPUDXESMM_H__ */