/** @file

Copyright (c) 2019-2023, Intel Corporation. All rights reserved.<BR>

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors may
  be used to endorse or promote products derived from this software without
  specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  THE POSSIBILITY OF SUCH DAMAGE.

**/

#ifndef _SYSTEM_INFO_HOB_H_
#define _SYSTEM_INFO_HOB_H_

#define SYSTEM_INFO_HOB_GUID          { 0x7650A0F2, 0x0D91, 0x4B0C, { 0x92, 0x3B, 0xBD, 0xCF, 0x22, 0xD1, 0x64, 0x35 }}

#ifndef MAX_SOCKET
#define MAX_SOCKET                    4
#endif

#ifndef MAX_IIO_STACK
#define MAX_IIO_STACK                 12
#endif

#define MAX_LOGIC_IIO_STACK           14

#ifndef MAX_IMC
#define MAX_IMC                       4                     // Maximum memory controllers per socket
#endif

#ifndef MAX_MC_CH
#define MAX_MC_CH                     2                     // Max number of channels per MC (3 for EP)
#endif

#ifndef MAX_CH
#define MAX_CH                        ((MAX_IMC)*(MAX_MC_CH))     // Max channels per socket (worst case EP * EX combination = 16)
#endif

#define MAX_HPM_PFS_ENTRY_NUM         15      // Number of entries in PFS structure
#define HPM_PFS_ENTRY_SIZE            2       // Entry size of PFS structure in DWORD

#pragma pack(1)

#ifndef MMIO_BARS_ENUM
#define MMIO_BARS_ENUM
typedef enum {
  TYPE_SCF_BAR = 0,
  TYPE_PCU_BAR,
  TYPE_MEM_BAR0,
  TYPE_MEM_BAR1,
  TYPE_MEM_BAR2,
  TYPE_MEM_BAR3,
  TYPE_MEM_BAR4,
  TYPE_MEM_BAR5,
  TYPE_MEM_BAR6,
  TYPE_MEM_BAR7,
  TYPE_SBREG_BAR,
  TYPE_MAX_MMIO_BAR
} MMIO_BARS;
#endif

typedef enum {
  ReservedMemSs,
  Ddr4MemSs = 1,
  Ddr5MemSs = 2,
  LpDdr4MemSs = 3,
  LpDdr5MemSs = 4,
  Hbm2MemSs = 5,
  MrcMstMax,
  MrcMstDelim = MAX_INT32
} MRC_MST;

typedef enum BootMode {
  NormalBoot  = 0,  // Normal path through RC with full init, mem detection, init, training, etc.
                    //    Some of these MRC specific init routines can be skipped based on MRC input params
                    //    in addition to the sub-boot type (WarmBoot, WarmBootFast, etc).
  S3Resume    = 1   // S3 flow through RC. Should do the bare minimum required for S3
                    //    init and be optimized for speed.
} BootMode;

//
// This is used to determine what type of die is connected to a UPI link
//
typedef enum {
  UpiConnectionTypeCpu,
  UpiConnectionTypePcieGen4,
  UpiConnectionTypeFpga,
  UpiConnectionTypeMax
} UPI_CONNECTION_TYPE;

//
// VSEC info for HPM
// The HPM_INFO struct contains info collected from the VSEC structure for the HPM.
// VSEC Structure is defined as below:
//
// ------------------------VSEC Structure------------------------
// | Next Cap Offset(12b)  | Cap Version(4b) | PCIe Cap ID(16b) |
// --------------------------------------------------------------
// |     VSEC_LEN(12b)     |   VSEC_REV(4b)  |   VSEC_ID(16b)   |
// --------------------------------------------------------------
// | EntrySize(8b)     |     NumEntries(8b)  |    Rsvd(16b)     |
// --------------------------------------------------------------
// |                 Address(29b)                    | tBIR(3b) |
// --------------------------------------------------------------
//
//
typedef struct {
  UINT8        NumEntries;  // The number of PM feature interface instances in this VSEC space
  UINT8        EntrySize;   // The entry size for each PM interface instance in 32-bit DWORDs
  UINT32       Address;     // The offset from the BAR register which is used for HPM to point to the base of the discovery entry. i.e. the PFS (PM Feature Structure)
  UINT8        tBIR;        // Which one of he function's BAR is used for the PFS offset
} HPM_INFO;

//
//-------------------------------- - PFS Entry--------------------------------
//|  EntrySize(16b)                     |  NumEntries(8b)  |  VSEC_SubID(8b)  |
//----------------------------------------------------------------------------
//| RSVD(14b)                | Attr(2b) |       CapOffset(16b)                |
//----------------------------------------------------------------------------
//
typedef struct {
  UINT32                TpmiId : 8;
  UINT32                NumEntries : 8;
  UINT32                EntrySize : 16;
  UINT32                CapOffset : 16;
  UINT32                Attribute : 2;
  UINT32                EntryBitMap : 8;
  UINT32                Rsvd : 6;
} PFS_ENTRY;

//
// HPM (Hierarchical Power Management) VSEC resource allocation info
//
typedef struct {
  BOOLEAN             HpmEnabled;                   // HPM enabled or not in BIOS knob
  BOOLEAN             HpmInfraReady;                // All the HPM infrastructure data is buffered
  UINT32              OobMsmHpmBarBase;               // The base of OOBMSM BAR1 for HPM PFS and LUT tables
  UINT32              OobMsmHpmBarLimit;              // The limit of OOBMSM BAR1 from where the required size will be allocated
  UINT32              OobMsmHpmBarMmcfgAddress;       // The OOBMSM BAR1 MMCFG address
  UINT32              OobMsmHpmBarRequiredSize;       // The required size of OOBMSM BAR1

  HPM_INFO            HpmVsecInfo;                  // For now, single VSEC is assumed
  PFS_ENTRY           Pfs[MAX_HPM_PFS_ENTRY_NUM];   // The buffered PFS structure

} HPM_VSEC_RESOURCE;

//
// Stack id swap information, which includes stack swap flag and the new stack id swap array.
//
typedef struct {
  BOOLEAN StackSwapFlag;
  UINT8   StackIdSwapArray[MAX_IIO_STACK];
} STACKID_SWAP_INFO;

typedef struct {
  UINT64  Cxl1p1RcrbBase;
  BOOLEAN Cxl1p1RcrbValid;
} CXL_1P1_RCRB;

typedef struct {
  UINT32 StackPresentBitmap[MAX_SOCKET];           ///< bitmap of present stacks per socket
  UINT8  StackBus[MAX_SOCKET][MAX_LOGIC_IIO_STACK];///< Bus of each stack
  UINT32 StackMmiol[MAX_SOCKET][MAX_IIO_STACK];    ///< mmiol of each IIO stack, if it works as CXL, the mmiol base is RCRBBAR
  UINT8  SocketFirstBus[MAX_SOCKET];
  UINT8  Socket10nmUboxBus0[MAX_SOCKET];           //10nm CPU use only
  UINT8  TotIoDie[MAX_SOCKET];                     //GNR & SRF CPU use only
  UINT8  TotCmpDie[MAX_SOCKET];                    //GNR & SRF CPU use only
  UINT8  SocketLastBus[MAX_SOCKET];
  UINT8  segmentSocket[MAX_SOCKET];
  UINT8  KtiPortCnt;
  UINT32 socketPresentBitMap;
  UINT32 SecondaryNodeBitMap;
  UINT32 FpgaPresentBitMap;
  UINT32 mmCfgBase;
  UINT64 SocketMmCfgBase[MAX_SOCKET];
  UINT8  DdrMaxCh;
  UINT8  DdrMaxImc;                               ///< Logical number of IMC count, ignoring logical holes
  UINT8  DdrPhysicalMaxImc;                       ///< Physical number of IMC count from Capid
  UINT8  DdrNumChPerMc;
  UINT8  DdrNumPseudoChPerCh;
  UINT8  imcEnabled[MAX_SOCKET][MAX_IMC];
  UINT8  mcId[MAX_SOCKET][MAX_CH];
  MRC_MST MemSsType[MAX_SOCKET];                    ///< MemSsType global identifier for DDR vs. HBM
  UINT32  MmioBar[MAX_SOCKET][TYPE_MAX_MMIO_BAR];
  UINT8   HbmMaxCh;
  UINT8   HbmMaxIoInst;
  UINT8   HbmNumChPerMc;
  UINT8   HbmNumChPerIo;
  UINT32  LastCsrAddress[2];
  UINT32  LastCsrMmioAddr;
  UINT8   CsrCachingEnable;
  UINT32  LastCsrMcAddress[2];
  UINT32  LastCsrMcMmioPhyAddr;
  UINT8   CsrPciBarCachingEnable;
  UINT32  LastCsrPciBarAddr[2];
  UINT64  LastCsrPciBarPhyAddr;
  UINT32  LastSBPortId[MAX_SOCKET];
  UPI_CONNECTION_TYPE         UpiConnectionType[MAX_SOCKET];
  BOOLEAN PostedCsrAccessAllowed;                   // SW is allowed to use posted CSR writes method when TRUE
  BOOLEAN PostedWritesEnabled;                      // All CSR writes use posted method when TRUE, non-posted when FALSE
  BOOLEAN DataPopulated;                            // CPU_CSR_ACCESS_VAR is unavailable when FALSE
  HPM_VSEC_RESOURCE SocketHpmVsecRes[MAX_SOCKET];   // HPM VSEC info for all sockets
  BOOLEAN HbmSku;
  UINT8   HcxType[MAX_SOCKET];
  STACKID_SWAP_INFO StackIdSwapInfo[MAX_SOCKET];    //StackID sync after do StackId swap,including Stack swap table and whether do stack swap
  CXL_1P1_RCRB  Cxl1p1Rcrb[MAX_SOCKET][MAX_IIO_STACK];    // CXL 1.1 RCRB, one per PI5 stack
  UINT32  DmiRcrb[MAX_SOCKET];                      // DMI RCRB region, one per socket
  UINT8   FabricType;                               //Compute die 10x6, 10x5, and 6x5 type is stored
  UINT8   ChopType;                                 //Compute Die Chop Type
  UINT8   MdfInstCount;
} CPU_CSR_ACCESS_VAR;

typedef struct {
  UINT32 MeRequestedSizeNv;
  UINT32 MeRequestedAlignmentNv;
  UINT8  SbspSocketIdNv;
} SYS_INFO_VAR_NVRAM;

typedef struct _CPUID_REGISTER_INFO {
  UINT32 Eax;
  UINT32 Ebx;
  UINT32 Ecx;
  UINT32 Edx;
} CPUID_REGISTER_INFO;

typedef struct _PROCESSOR_COMMON_INFO {
  UINT32  capid0;
  UINT32  capid1;
  UINT32  capid2;
  UINT32  capid3;
  UINT32  capid4;
  UINT32  capid5;
  UINT32  capid6lo;
  UINT32  capid6hi;
  CPUID_REGISTER_INFO  ExtCpuid7;
  CPUID_REGISTER_INFO  ExtCpuid1B;
} PROCESSOR_COMMON_INFO;

typedef struct {
  UINT32 MeRequestedSize;
  UINT32 MeRequestedAlignment;
  UINT32 CheckPoint;
  UINT8  ResetRequired;
  UINT8  Emulation;
  BootMode SysBootMode;
  CPU_CSR_ACCESS_VAR        CpuCsrAccessVarHost;    // Common resource for CsrAccessRoutines
  UINT64   CpuFreq;
  UINT8    SocketId;
  SYS_INFO_VAR_NVRAM SysInfoVarNvram;
  BOOLEAN  UsraTraceControl;
  UINT16   UsraTraceConfiguration;                 // Bit               7       6        5           4                     3:0
                                                   //               Write, Modify, GetAddr, Long/Short, Trace 0x5 as signature
                                                   // Bit               15                              14:11   10     9     8
                                                   // DumpCpuCsrAccessVar,                                TBD, CSR, PCIE, Read
  BOOLEAN  CpuCsrAccessVarInfoDumped;
  PROCESSOR_COMMON_INFO          ProcessorCommonInfo[MAX_SOCKET];
  EFI_PHYSICAL_ADDRESS  SocAddrMapData;
  UINTN    UsraPpiPtr;
} SYSTEM_INFO_VAR;


#pragma pack ()

#endif //#ifndef _SYSTEM_INFO_HOB_H_
