Newer
Older
AMI-Aptio-BIOS-Reversed / PurleySktPkg / Dxe / CrystalRidge / CrystalRidgeSMM / CrystalRidgeSMM.c
@Ajax Dong Ajax Dong 2 days ago 22 KB Restructure the repo
/** @file CrystalRidgeSMM.c
 *  SMM Driver for Intel Crystal Ridge NVDIMM Controller
 *
 *  Reconstructed from CrystalRidgeSMM.efi (index 0175, port 13390)
 *  Source files: CrystalRidge.c, Nfit.c, Dsm.c, CrystalRidgeProtocol.c,
 *                PlatformCfgData.c, NvdimmAcpiConfig.c, ArsFlows.c,
 *                ArsFlowsPrivate.c, ArsErrorInject.c, Pcat.c,
 *                XlateFunctions.c, AcpiNotify.c, ShortArs.c,
 *                SmmCrystalRidgeFlushNearMemoryLib.c
 *
 *  Build path: e:\hs\PurleySktPkg\Dxe\CrystalRidge\
 *  Build config: HR6N0XMLK DEBUG_VS2015 X64
 */

#include "CrystalRidgeSMM.h"

// ===========================================================================
// Globals (reconstructed from .data section at 0x29600-0xAE580)
// ===========================================================================

EFI_HANDLE          gImageHandle_CR         = NULL;
EFI_SYSTEM_TABLE    *gST_CR                 = NULL;
EFI_BOOT_SERVICES   *gBS_CR                 = NULL;
EFI_RUNTIME_SERVICES *gRT_CR                = NULL;
EFI_SMM_SYSTEM_TABLE2 *gSmst_CR             = NULL;

UINT64              gCrReturnStatus         = 1;          // qword_29EB8
UINT8               gCrIsSmmOnly            = 0;          // byte_29CB0
UINT8               gCrIsSmm                = 0;          // byte_29CD9
UINT64              gCrCacheLineSizeMul     = 0;          // qword_29EC0

VOID                *gCrMcInfo              = NULL;        // qword_29CA0
VOID                *gCrNfit                = NULL;        // qword_29CA8
VOID                *gCrProtocol0           = NULL;        // qword_29CE0
VOID                *gCrProtocol1           = NULL;        // qword_29CD0

CR_DIMM_ENTRY       gCrDimmDb[CR_MAX_DIMM_ENTRIES];      // unk_6F6E8
CR_DIMM_ENTRY       gCrDimmDbFallback;                    // unk_AC2E8
UINT8               gCrDimmCount            = 0;          // byte_AE149

UINT32              gCrXlateTable[6]        = {0};        // dword_6F6E0
INT32               gCrXlateCount           = 0;          // dword_6F6E4
CR_CONTROL_REGION   gCrControlRegions[CR_MAX_CONTROL_REGIONS];  // qword_AE028
UINT8               gCrControlRegionCount   = 0;          // n8 in sub_67D4

// ===========================================================================
// Library Helpers
// ===========================================================================

/**
 * ASSERT-style debug print
 * Original: sub_20AF0 at 0x20AF0 (163 callers across the binary)
 */
VOID
CrystalRidgeDebugAssert(
    IN CONST CHAR8          *FileName,
    IN UINT32               LineNumber,
    IN CONST CHAR8          *AssertText
    )
{
    //
    // Wraps sub_20A58 to format and print assertion failure
    // Calls sub_20AA8 for final output
    //
}

/**
 * EFI_ERROR() macro check wrapper thunk
 * Original: sub_20B30 at 0x20B30 (82 callers)
 */
BOOLEAN
CrystalRidgeEfiError(
    VOID
    )
{
    //
    // Thunk - conditionally evaluates EFI_ERROR
    //
    return FALSE;
}

/**
 * Debug level enablement check
 * Original: sub_20B34 at 0x20B34 (38 callers)
 */
BOOLEAN
CrystalRidgeDebugEnabled(
    IN UINT64              DebugLevel
    )
{
    return (DebugLevel & 0x80000000LL) != 0;
}

/**
 * Copy memory wrapper
 * Original: sub_203B0 at 0x203B0 (30 callers)
 */
VOID *
CrystalRidgeCopyMem(
    OUT VOID               *Destination,
    IN CONST VOID           *Source,
    IN UINTN               Length
    )
{
    if (Length == 0) return Destination;
    // Validates buffer bounds
    // Thunks to internal rep movsb at sub_2D0
    return sub_2D0(Destination, Source, Length);
}

/**
 * Zero memory wrapper
 * Original: sub_2044C at 0x2044C (61 callers)
 */
VOID
CrystalRidgeZeroMem(
    OUT VOID               *Buffer,
    IN UINTN                Length
    )
{
    if (Length == 0) return;
    // Validates buffer bounds
    // Thunks to internal rep stosb at sub_320
}

/**
 * Translate EFI status code to human-readable error string
 * Original: sub_8FAC at 0x8FAC (16 callers)
 * Maps EFI error codes to short integer categories for mailbox status
 */
UINT16
CrystalRidgeStatusToCategory(
    IN BOOLEAN             IsSmmContext,
    IN INT32               ErrorCode,
    IN UINT64              RawStatus
    )
{
    if (ErrorCode > 255)
        return (UINT16)(6 - (IsSmmContext ? 1 : 0));
    // Complex switch tree mapping error codes 0..255 and
    // EFI_STATUS values to category codes 0..11
    // Categories: Success(0), InvalidParam(3), NotReady(4),
    // DeviceError(5), Timeout(2), etc.
    return 0;
}

// ===========================================================================
// Module Entry Point (0x5A0)
// ===========================================================================

EFI_STATUS
EFIAPI
CrystalRidgeSmmEntryPoint(
    IN EFI_HANDLE           ImageHandle,
    IN EFI_SYSTEM_TABLE     *SystemTable
    )
{
    EFI_STATUS  Status;

    //
    // Initialize global UEFI service table pointers (sub_5DC at 0x5DC)
    // Handles: gImageHandle, gST, gBS, gRT, gSmst, gPcd
    //
    CrystalRidgeInitServiceTablePointers(ImageHandle, SystemTable);

    //
    // Call main driver initialization (sub_A00 -> sub_798C)
    //
    Status = CrystalRidgeSmmDriverInit(ImageHandle, SystemTable);

    //
    // If installation failed, trigger assert
    //
    if (Status < 0) {
        CrystalRidgeAbort();
    }

    return Status;
}

// ===========================================================================
// Service Table Initialization (sub_5DC at 0x5DC)
// ===========================================================================

EFI_STATUS
CrystalRidgeInitServiceTablePointers(
    IN EFI_HANDLE           ImageHandle,
    IN EFI_SYSTEM_TABLE     *SystemTable
    )
{
    EFI_STATUS              Status;
    EFI_SMM_BASE2_PROTOCOL  *SmmBase2;

    gImageHandle_CR = ImageHandle;
    ASSERT(gImageHandle_CR != NULL);

    gST_CR = SystemTable;
    ASSERT(gST_CR != NULL);

    gBS_CR = SystemTable->BootServices;
    ASSERT(gBS_CR != NULL);

    gRT_CR = SystemTable->RuntimeServices;
    ASSERT(gRT_CR != NULL);

    //
    // Locate SMM Base2 protocol to detect SMM context
    //
    Status = gBS_CR->LocateProtocol(
                        &gEfiSmmBase2ProtocolGuid,
                        NULL,
                        (VOID **)&SmmBase2
                        );
    if (EFI_ERROR(Status)) {
        gCrIsSmm = FALSE;
        return Status;
    }

    Status = SmmBase2->InSmm(SmmBase2, &gCrIsSmm);
    ASSERT_EFI_ERROR(Status);

    if (gCrIsSmm) {
        Status = SmmBase2->GetSmstLocation(SmmBase2, (VOID **)&gSmst_CR);
        ASSERT(gSmst_CR != NULL);
    }

    //
    // Setup PCD database pointer via DxePcdLib
    //
    ASSERT(mPcd != NULL);

    return EFI_SUCCESS;
}

// ===========================================================================
// Main Driver Initialization (sub_798C at 0x798C)
// ===========================================================================

EFI_STATUS
CrystalRidgeSmmDriverInit(
    IN EFI_HANDLE           ImageHandle,
    IN EFI_SYSTEM_TABLE     *SystemTable
    )
{
    EFI_STATUS              Status;
    UINT8                   IsSmmContext;
    UINT32                  VariableSize;
    UINT8                   ConfigData[312];

    //
    // Step 1: Determine execution context (SMM or DXE)
    //
    Status = gBS_CR->LocateProtocol(
                        &gUnknownProtocolGuid,
                        NULL,
                        &gCrProtocol0
                        );

    if (!EFI_ERROR(Status) && gCrProtocol0 != NULL) {
        //
        // SMM path: Get protocol interface pointers
        //
        gCrProtocol1 = *(VOID **)gCrProtocol0;
        IsSmmContext = *(UINT8 *)gCrProtocol1;
        gCrIsSmm = IsSmmContext;

        //
        // Step 2: Locate mCrInfo protocol via protocol interface
        //
        Status = ((PROTOCOL_INTERFACE *)gCrProtocol1)->LocateProtocol(
                    &gCrInfoProtocolGuid,
                    NULL,
                    &gCrMcInfo
                    );
        if (EFI_ERROR(Status)) {
            CrystalRidgeDebugAssert(
                "CrystalRidge.c", 4012,
                "!EFI_ERROR (Status)"
                );
        }

        //
        // Step 3: Locate additional protocol for shared data
        //
        Status = ((PROTOCOL_INTERFACE *)gCrProtocol1)->LocateProtocol(
                    &gCrSharedDataGuid,
                    NULL,
                    &gCrSharedData
                    );
        if (EFI_ERROR(Status)) {
            CrystalRidgeDebugAssert(
                "CrystalRidge.c", 4015,
                "!EFI_ERROR (Status)"
                );
        }

        //
        // Step 4: Register SMI notification for command type 25037
        //
        Status = ((PROTOCOL_INTERFACE *)gCrProtocol1)->Register(
                    6, 25037, &gCrSmiNotify
                    );
        if (EFI_ERROR(Status)) {
            CrystalRidgeDebugAssert(
                "CrystalRidge.c", 4021,
                "!EFI_ERROR (Status)"
                );
        }
    } else {
        //
        // Non-SMM (DXE) path
        //
        gCrIsSmmOnly = TRUE;

        Status = gBS_CR->LocateProtocol(
                            &gCrInfoProtocolGuid,
                            NULL,
                            &gCrMcInfo
                            );
        //
        // Register SMI notification via Boot Services
        //
        Status = gBS_CR->RegisterProtocolNotify(
                        4, 25037, &gCrSmiNotify
                        );
    }

    //
    // Step 5: Read SocketProcessorCoreConfig UEFI variable
    //
    VariableSize = 301;
    Status = gRT_CR->GetVariable(
                        L"SocketProcessorCoreConfig",
                        &gEfiVariableGuid,
                        NULL,
                        &VariableSize,
                        ConfigData
                        );
    if (EFI_ERROR(Status)) {
        // Parse config HOB if variable not available
        Status = CrystalRidgeParseConfigHob(&ConfigData);
    }

    //
    // Step 6: Initialize DIMM database from protocol data (sub_6DD0)
    //
    CrystalRidgeInitDimmDb();

    //
    // Step 7: Read cache line size via CPUID
    //
    gCrCacheLineSizeMul = CrystalRidgeGetCacheLineSize() * 8;

    //
    // Step 8: Configure SMI translation tables for NVDIMM (32) and ARS (4)
    //
    CrystalRidgeConfigureSmi(32);    // NVDIMM command type
    CrystalRidgeConfigureSmi(4);     // ARS command type

    return Status;
}

// ===========================================================================
// DIMM Database Initialization (sub_6DD0 at 0x6DD0)
// ===========================================================================

UINT64
CrystalRidgeInitDimmDb(
    VOID
    )
{
    UINT16  Socket;
    UINT8   Channel;
    UINT8   Dimm;

    //
    // Iterate 4 sockets, 6 channels per socket, 2 DIMMs per channel
    //
    for (Socket = 0; Socket < CR_MAX_SOCKETS; Socket++) {
        for (Channel = 0; Channel < CR_MAX_CHANNELS_PER_SOCKET; Channel++) {
            for (Dimm = 0; Dimm < CR_MAX_DIMMS_PER_CHANNEL; Dimm++) {
                //
                // Check if DIMM is present via mCrInfo data
                //
                if (CrystalRidgeIsDimmPresent(Socket, Channel, Dimm)) {
                    //
                    // Check if DIMM is already initialized
                    //
                    if (!gCrDimmDb[gCrDimmCount].Ptr) {
                        //
                        // Populate new DIMM entry
                        //
                        gCrDimmDb[gCrDimmCount].SocketId = Socket;
                        gCrDimmDb[gCrDimmCount].Channel  = Channel;
                        gCrDimmDb[gCrDimmCount].DimmSlot = Dimm;
                        gCrDimmDb[gCrDimmCount].Ptr      = 0;
                        gCrDimmCount++;
                    }
                }
            }
        }
    }

    return Socket;
}

// ===========================================================================
// DIMM Lookup (sub_2794 at 0x2794)
// ===========================================================================

CR_DIMM_ENTRY *
CrystalRidgeFindDimm(
    IN UINT8                SocketId,
    IN UINT8                Channel,
    IN UINT8                DimmSlot,
    IN UINT8                Flags
    )
{
    UINT8           Index;

    //
    // Linear search through DIMM database
    //
    for (Index = 0; Index < gCrDimmCount; Index++) {
        if (gCrDimmDb[Index].SocketId == SocketId &&
            gCrDimmDb[Index].DimmSlot  == DimmSlot  &&
            gCrDimmDb[Index].Channel   == Channel   &&
            ((Flags & 1) || gCrDimmDb[Index].Ptr != 0))
        {
            return &gCrDimmDb[Index];
        }
    }

    //
    // Return fallback entry if Flag 2 set
    //
    if (Flags & 2) {
        return &gCrDimmDbFallback;
    }

    return NULL;
}

// ===========================================================================
// SMI Configuration (sub_67D4 at 0x67D4)
// ===========================================================================

UINT64
CrystalRidgeConfigureSmi(
    IN UINT16               ConfigType
    )
{
    UINT8   Socket;
    UINT8   Channel;
    UINT8   Dimm;

    //
    // Iterate all sockets, channels, DIMMs to configure translation
    //
    for (Socket = 0; Socket < CR_MAX_SOCKETS; Socket++) {
        for (Channel = 0; Channel < CR_MAX_CHANNEL_ENTRIES; Channel++) {
            Dimm = 24 * Socket + Channel;

            if (/* DIMM present and has matching type */) {
                //
                // For ConfigType=32 (NVDIMM): Set up control regions
                //
                if (ConfigType == 32) {
                    // Initialize translation table on first invocation
                    if (/* first time */) {
                        gCrXlateTable[0] = CrystalRidgeGetXlateBase(/* Dimm */);
                        gCrXlateCount = CrystalRidgeGetXlateCount(/* Dimm */);
                    }

                    // Determine topology and set control region
                    UINT8 TopoType = CrystalRidgeGetTopology(Socket, Channel, Dimm);
                    UINT64 BaseAddr = /* calculated base */;

                    gCrControlRegions[gCrControlRegionCount].Base = BaseAddr;

                    switch (TopoType) {
                    case 1: // SAD
                        CrystalRidgeSetSadTopology(Socket, BaseAddr);
                        break;
                    case 2: // SAD_BASE
                        CrystalRidgeSetSadBaseTopology(Socket, BaseAddr);
                        break;
                    case 3: // CR
                        CrystalRidgeSetCrTopology(Socket, BaseAddr);
                        break;
                    }

                    if (gCrControlRegions[gCrControlRegionCount].Size != 0) {
                        gCrControlRegionCount++;
                    }
                }
                //
                // For ConfigType=4 (ARS): Set up ARS regions
                //
                else if (ConfigType == 4) {
                    // Similar topology-based setup for ARS
                    UINT8 TopoType = CrystalRidgeGetTopology(...);
                    switch (TopoType) {
                    case 1:
                        CrystalRidgeSetArsSad(...);
                        break;
                    case 2:
                        CrystalRidgeSetArsSadBase(...);
                        break;
                    case 3:
                        CrystalRidgeSetArsCr(...);
                        break;
                    }
                }
            }
        }
    }

    //
    // Finalize: fill remaining control regions with defaults
    //
    if (ConfigType == 32) {
        for (/* remaining slots */) {
            gCrControlRegions[...].Base = &gCrDimmDbFallback;
            gCrControlRegions[...].Size = 280;
        }
    }

    return ConfigType;
}

// ===========================================================================
// Translation and Mailbox
// ===========================================================================

/**
 * Translate physical address to DIMM offset
 * sub_152CC at 0x152CC
 */
EFI_STATUS
CrystalRidgeTranslateAddress(
    IN VOID                 *TranslationInfo,
    IN UINT64               Address,
    IN INT32                RegionType,
    OUT UINT64              *DimmOffset
    )
{
    if (TranslationInfo == NULL || DimmOffset == NULL) {
        return EFI_INVALID_PARAMETER;
    }

    // Determine if address is in HOB table or direct
    UINT8   Socket;
    UINT8   Channel;
    UINT8   Dimm;

    if (CrystalRidgeIsHobAddress(Address)) {
        Socket = *(UINT8 *)(TranslationInfo + 6);
        Channel = *(UINT8 *)(TranslationInfo + 2);
        // Look up in translation table
        INT32 Index = CrystalRidgeFindXlateEntry(Address, Socket, Channel);
        if (Index == -1) return EFI_INVALID_PARAMETER;
        Socket = gCrPerDimmData[Index * 6];     // byte_3E058
        Channel = gCrPerDimmData[Index * 6 + 4]; // byte_3E05C
        Dimm  = gCrPerDimmData[Index * 6 + 5];  // byte_3E05D
    } else {
        Address  = *(UINT64 *)(TranslationInfo + 16);
        Socket   = *(UINT8 *)(TranslationInfo + 5);
        Channel  = *(UINT8 *)(TranslationInfo + 7);
        Dimm     = *(UINT8 *)(TranslationInfo + 8);
    }

    // Apply SAD/interleave translation
    *DimmOffset = Address + CrystalRidgeApplyTranslation(
                                RegionType, Socket, Channel, Dimm,
                                gCrXlateCount, gCrXlateTable[0]
                                );

    return EFI_SUCCESS;
}

/**
 * Send mailbox command to NVDIMM hardware
 * sub_F200 at 0xF200
 */
EFI_STATUS
CrystalRidgeMailboxCommand(
    IN UINT8                SocketId,
    IN UINT8                Channel,
    IN UINT8                DimmSlot,
    IN UINT32               Command,
    IN VOID                 *Buffer,
    IN UINT32               InputSize,
    IN UINT32               OutputSize,
    IN UINT8                IsLongOp
    )
{
    CR_DIMM_ENTRY   *Dimm;
    EFI_STATUS      Status;

    if (Buffer == NULL) {
        return EFI_INVALID_PARAMETER;
    }
    if (OutputSize == 0) {
        return EFI_SUCCESS;
    }

    //
    // Find the DIMM entry
    //
    Dimm = CrystalRidgeFindDimm(SocketId, Channel, DimmSlot, 0);
    if (Dimm == NULL) {
        return EFI_INVALID_PARAMETER;
    }

    //
    // Send command via hardware mailbox interface
    //
    if (IsLongOp) {
        Status = CrystalRidgeMailboxLongOp(Dimm, Command, Buffer, InputSize, OutputSize);
    } else {
        Status = CrystalRidgeMailboxShortOp(Dimm, Command, Buffer, InputSize, OutputSize);
        if (!EFI_ERROR(Status)) {
            if (CrystalRidgeIsMailboxBusy(Dimm)) {
                // Retry once if busy
                Status = CrystalRidgeMailboxShortOp(Dimm, Command, Buffer, InputSize, OutputSize);
            }
        }
    }

    return Status;
}

// ===========================================================================
// NFIT Construction (sub_1FDFC at 0x1FDFC)
// ===========================================================================

VOID
CrystalRidgeNfitBuild(
    IN INT32                Socket,
    IN INT32                Channel,
    IN INT32                Dimm,
    IN INT32                RegionType,
    IN UINT8                Flags
    )
{
    //
    // Build NFIT structure for given DIMM/region
    //
    CrystalRidgeNfitBuildEntry(Socket, Channel, Dimm, RegionType, Flags);

    //
    // Update NFIT table header
    //
    ((NFIT_TABLE *)gCrNfit)->StructureCount++;
    ((NFIT_TABLE *)gCrNfit)->UpdateRequired = TRUE;
}

// ===========================================================================
// Protocol Setup (sub_7118 at 0x7118)
// ===========================================================================

UINT64
CrystalRidgeSetupProtocol(
    IN UINT8                *Buffer
    )
{
    //
    // Initialize protocol callback buffer
    //
    CrystalRidgeZeroMem(Buffer, sizeof(CR_PROTOCOL_BUFFER));

    //
    // Set default values and populate from mCrInfo data
    //
    // Iterate 4 sockets, 24 channels to discover active DIMMs
    // and set topology configuration bytes
    //
    for (UINT8 Socket = 0; Socket < CR_MAX_SOCKETS; Socket++) {
        for (UINT8 Channel = 0; Channel < CR_MAX_CHANNEL_ENTRIES; Channel++) {
            UINT8 *DimmEntry = (UINT8 *)(gCrMcInfo + CR_SOCKET_STRIDE * Socket +
                                         2956 + CR_PER_CHANNEL_ENTRY_SIZE * Channel + 213);
            if (*DimmEntry &&
                *(DimmEntry + 14) &&
                *(UINT16 *)(DimmEntry + 1) == 2)
            {
                for (UINT8 SubChannel = 0; SubChannel < 2; SubChannel++) {
                    UINT8 Mask = DimmEntry[SubChannel + 9];
                    UINT8 BitPos = 0;
                    while (Mask) {
                        if (Mask & 1) {
                            *(Buffer + 8 * Socket + 120 + BitPos + 3 * SubChannel) = 17;
                        }
                        BitPos++;
                        Mask >>= 1;
                    }
                }
            }
        }
    }

    //
    // Configure flags and timeouts
    //
    *(UINT32 *)(Buffer + 116) |= 2;
    *(UINT32 *)(Buffer + 116) &= ~4;
    if (*(UINT8 *)(gCrMcInfo + 2919) == 1) {
        *(UINT32 *)(Buffer + 116) |= 4;
    }

    *(UINT8 *)(Buffer + 312) = 0xFF;
    *(UINT32 *)(Buffer + 112) = CrystalRidgeGetTimerTick();
    *(UINT8 *)(Buffer + 83)  = *(UINT8 *)(gCrMcInfo + 2851);
    *(UINT8 *)(Buffer + 315) = 1;

    return (UINT64)Buffer;
}

// ===========================================================================
// Flush Near Memory Cache (SmmCrystalRidgeFlushNearMemoryLib)
// ===========================================================================

/**
 * Initialize near-memory cache flush mechanism
 * sub_23A10 at 0x23A10
 */
EFI_STATUS
CrystalRidgeFlushNearMemoryInit(
    IN VOID                 *Context
    )
{
    if (Context == NULL) {
        CrystalRidgeDebugAssert(
            __FILE__, __LINE__, "((BOOLEAN)(0==1))"
            );
        return EFI_INVALID_PARAMETER;
    }

    //
    // Perform flush initialization
    // - Register SMI handlers for flush
    // - Setup GPI interrupt for S5 transition
    // - Configure EADR mode
    //
    CrystalRidgeFlushInternalInit();

    //
    // Register reset notification callback
    //
    CrystalRidgeRegisterResetCallback();

    return EFI_SUCCESS;
}