/** @file
  SmbiosDataUpdateDxeNeonCityFPGA -- UBA SMBIOS Data Update Driver for NeonCityFPGA platform.

  This DXE driver is part of the Lenovo UBA (Unified Board Architecture) framework
  for the ThinkSystem HR650X. It updates SMBIOS type 8 (Port Connector), type 9
  (System Slots), and type 41 (Onboard Devices Extended Information) tables with
  platform-specific data read via MMIO/PCI config space (MmPciBase protocol).

  The driver:
    1. Locates and caches all required UEFI protocols
    2. Registers a callback with the UBA SmbiosUpdate protocol
    3. The callback builds SMBIOS records by reading hardware configuration
       via PCI config cycles through gMmPciBase (USRA protocol)
    4. Applies HII string overrides from the module's embedded HII package list

  Processor: X64
  File path:  HR650X_3647_AJAX_BIOS_ORIGINAL.pe_structured/pe_files/0008_.../
  Build path: e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\...
              PurleyRpPkg\\Uba\\UbaMain\\Dxe\\TypeNeonCityFPGA\\SmbiosDataUpdateDxe
  PDB:        ...\\SmbiosDataUpdateDxeNeonCityFPGA.pdb

  GUIDs used:
    - gUbaSmbiosUpdateProtocolGuid: E03E0D46-5263-4845-B0A4-58D57B3177E2
    - gEfiSmbiosProtocolGuid:       03583FF6-CB36-4940-947E-B9B39F4AFAFF
    - gEfiHiiDatabaseProtocolGuid:  587E72D7-CC50-4F79-8209-CA291FC1A1...
    - gEfiHiiStringProtocolGuid:    31A6406A-6BDF-4E46-B2A2-EBAA89C409...
    - gEfiHiiConfigRoutingGuid:     EF9FC172-A1B2-4693-B327-6D32FC4160...
    - gEfiHiiFontProtocolGuid:      0FD96974-23AA-4CDC-B9CB-98D1775032...
    - gEfiHiiImageProtocolGuid:     E9CA4775-8657-47FC-97E7-7ED65A0843...
    - gEfiMmPciBaseGuid:            FD480A76-B134-4EF7-ADFE-B0E0546398...
    - gEfiHobListGuid:              7739F24C-93D7-11D4-9A3A-0090273FC14D
    - gEfiDxeServicesTableGuid:     05AD34BA-6F02-4214-952E-4DA0398E2B...
    - gEfiHiiPackageListGuid:       5B1B31A1-9562-11D2-8E3F-00A0C96972
    - gEfiPlatformLangGuid:         8BE4DF61-93CA-11D2-AA0D-00E098032B
**/

#ifndef __SMBIOS_DATA_UPDATE_DXE_NEONCITY_FPGA_H__
#define __SMBIOS_DATA_UPDATE_DXE_NEONCITY_FPGA_H__

#include "../uefi_headers/Uefi.h"
#include "../uefi_headers/Protocol/Smbios.h"
#include "../uefi_headers/Protocol/HiiString.h"
#include "../uefi_headers/Protocol/HiiDatabase.h"
#include "../uefi_headers/Protocol/MmPciBase.h"

// ---------------------------------------------------------------------------
// GUID definitions
// ---------------------------------------------------------------------------

#define UBA_SMBIOS_UPDATE_PROTOCOL_GUID \
  { 0xE03E0D46, 0x5263, 0x4845, { 0xB0, 0xA4, 0x58, 0xD5, 0x7B, 0x31, 0x77, 0xE2 }}

#define EFI_MM_PCI_BASE_PROTOCOL_GUID \
  { 0xFD480A76, 0xB134, 0x4EF7, { 0xAD, 0xFE, 0xB0, 0xE0, 0x54, 0x63, 0x98, 0x07 }}

// ---------------------------------------------------------------------------
// SMBIOS type constants used in this module
// ---------------------------------------------------------------------------

#define SMBIOS_TYPE_PORT_CONNECTOR  8   ///< SMBIOS type 8: Port Connector Information
#define SMBIOS_TYPE_SYSTEM_SLOTS    9   ///< SMBIOS type 9: System Slot Information
#define SMBIOS_TYPE_ONBOARD_DEVICE  41  ///< SMBIOS type 41: Onboard Devices Extended Info

// ---------------------------------------------------------------------------
// HII string token IDs for SMBIOS string overrides
// ---------------------------------------------------------------------------

/// String token IDs used in sub_77C (type 8 port connector strings).
/// These correspond to strings embedded in the HII package list at 0x31F0.
#define STR_TOKEN_TYPE08_00  16   ///< Token 16: string for slot/port arrangement
#define STR_TOKEN_TYPE08_01  3    ///< Token 3:  port type descriptor
#define STR_TOKEN_TYPE08_02  4    ///< Token 4:  port type descriptor
#define STR_TOKEN_TYPE08_03  5    ///< Token 5:  port type descriptor
#define STR_TOKEN_TYPE08_04  7    ///< Token 7:  port type descriptor
#define STR_TOKEN_TYPE08_05  8    ///< Token 8:  port type descriptor
#define STR_TOKEN_TYPE08_06  9    ///< Token 9:  port type descriptor
#define STR_TOKEN_TYPE08_07  10   ///< Token 10: port type descriptor
#define STR_TOKEN_TYPE08_08  11   ///< Token 11: port type descriptor
#define STR_TOKEN_TYPE08_09  12   ///< Token 12: port type descriptor
#define STR_TOKEN_TYPE08_10  13   ///< Token 13: port type descriptor
#define STR_TOKEN_TYPE08_11  15   ///< Token 15: port type descriptor
#define STR_TOKEN_TYPE08_12  16   ///< Token 16: port type descriptor
#define STR_TOKEN_TYPE08_13  17   ///< Token 17: port type descriptor
#define STR_TOKEN_TYPE08_14  19   ///< Token 19: port type descriptor
#define STR_TOKEN_TYPE08_15  20   ///< Token 20: port type descriptor
#define STR_TOKEN_TYPE08_16  21   ///< Token 21: port type descriptor
#define STR_TOKEN_TYPE08_17  22   ///< Token 22: port type descriptor
#define STR_TOKEN_TYPE08_18  23   ///< Token 23: port type descriptor (actually 0x17=23)

/// String token IDs used in sub_A20 (type 9 system slot strings).
#define STR_TOKEN_TYPE09_00  24   ///< Token 24: slot designation
#define STR_TOKEN_TYPE09_01  26   ///< Token 26: slot designation
#define STR_TOKEN_TYPE09_02  8    ///< Token 8:  slot designation
#define STR_TOKEN_TYPE09_03  16   ///< Token 16: slot designation
#define STR_TOKEN_TYPE09_04  18   ///< Token 18: slot designation
#define STR_TOKEN_TYPE09_05  25   ///< Token 25: slot designation
#define STR_TOKEN_TYPE09_06  26   ///< Token 26: slot designation
#define STR_TOKEN_TYPE09_07  27   ///< Token 27: slot designation

/// String token IDs used in sub_D98 (type 41 onboard device strings).
#define STR_TOKEN_TYPE41_00  28   ///< Token 28: device description (reference designator)
#define STR_TOKEN_TYPE41_01  29   ///< Token 29: device description
#define STR_TOKEN_TYPE41_02  30   ///< Token 30: device description
#define STR_TOKEN_TYPE41_03  31   ///< Token 31: device description

// ---------------------------------------------------------------------------
// SMBIOS record buffer layout (768 bytes allocated per record)
// ---------------------------------------------------------------------------
#define SMBIOS_RECORD_BUFFER_SIZE  768   ///< Temp buffer for constructing SMBIOS records
#define SMBIOS_MAX_STRING_LENGTH   65    ///< Max ascii string length for SMBIOS strings
#define SMBIOS_STRING_SCRATCH_SIZE 0x300 ///< Scratch buffer for string concatenation

// ---------------------------------------------------------------------------
// UBA SmbiosUpdate Protocol interface
// ---------------------------------------------------------------------------

// The UBA SmbiosUpdate protocol is an EFI protocol identified by
// gUbaSmbiosUpdateProtocolGuid. The interface structure is:
//
// typedef struct {
//   UINT64    Revision;              // +0x00
//   EFI_STATUS (*UpdateSmbios)(     // +0x10 -- callback for SMBIOS record updates
//     struct _UBA_SMBIOS_UPDATE_PROTOCOL  *This,
//     VOID                              *Buffer,   // rcx
//     UINTN                              BufferSize // rdx
//   );
// } UBA_SMBIOS_UPDATE_PROTOCOL;

// ---------------------------------------------------------------------------
// SmbiosRecordBuffer struct -- temp buffer layout for SMBIOS record building
// ---------------------------------------------------------------------------
//
// The buffer is allocated at sub_F54+0xa via sub_137C(768). sub_123C zerofills.
// Layout (relative to buffer start):
//   +0x00: UINT8   Type          (SMBIOS type: 8, 9, or 41)
//   +0x01: UINT8   Length        (structure length, varies by type)
//   +0x02: UINT16  Handle        (initialized to 0xFFFE = unassigned)
//   +0x04: UINT8   ... type-specific fields ...
//   +0x0N: STRING1\0STRING2\0...\0\0  (string area, appended after fixed fields)

// ---------------------------------------------------------------------------
// Forward declarations
// ---------------------------------------------------------------------------

EFI_STATUS
EFIAPI
ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

#endif /* __SMBIOS_DATA_UPDATE_DXE_NEONCITY_FPGA_H__ */