summaryrefslogtreecommitdiffstats
path: root/src/usr/hdat
diff options
context:
space:
mode:
authornagurram-in <nagendra.g@in.ibm.com>2017-08-07 07:00:32 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-08-22 10:05:44 -0400
commit6a8caef78b3bd678fa9412c9734f23bc523ad37e (patch)
tree8595624325051db04e4c8de59db2971b4c70a6bc /src/usr/hdat
parent818acb95a2dc8ff8e94c652e0964f013c1bf34cb (diff)
downloadtalos-hostboot-6a8caef78b3bd678fa9412c9734f23bc523ad37e.tar.gz
talos-hostboot-6a8caef78b3bd678fa9412c9734f23bc523ad37e.zip
SMP and slot map structures with hardcodes sourced from MRW
Change-Id: I1bf28f9136edd07c76adfaf07411fc12d5f8025e Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44277 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: VENKATESH SAINATH <venkatesh.sainath@in.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/hdat')
-rw-r--r--src/usr/hdat/hdatiohub.C190
-rwxr-xr-xsrc/usr/hdat/hdatiohub.H87
-rw-r--r--src/usr/hdat/hdatpcrd.C57
-rw-r--r--src/usr/hdat/hdatpcrd.H6
-rw-r--r--src/usr/hdat/hdatutil.C178
-rwxr-xr-xsrc/usr/hdat/hdatutil.H63
6 files changed, 571 insertions, 10 deletions
diff --git a/src/usr/hdat/hdatiohub.C b/src/usr/hdat/hdatiohub.C
index cf7e40df9..adef08e3f 100644
--- a/src/usr/hdat/hdatiohub.C
+++ b/src/usr/hdat/hdatiohub.C
@@ -76,6 +76,13 @@ const HdatKeywordInfo l_pvpdKeywords[] =
extern trace_desc_t *g_trac_hdat;
const uint32_t HDAT_MULTIPLE = 16;
+const uint32_t PROC0_NUM_SLOT_TABLE_AREAS = 14;
+const uint32_t PROC1_NUM_SLOT_TABLE_AREAS = 13;
+const uint32_t PROC0_NUM_SLOT_ENTRY_INFO = 2;
+const uint32_t PROC1_NUM_SLOT_ENTRY_INFO = 3;
+const uint32_t MAX_NUM_OF_PROCS = 2;
+const uint32_t MAX_NUM_OF_SLOT_TABLE_AREAS = (PROC0_NUM_SLOT_TABLE_AREAS > PROC1_NUM_SLOT_TABLE_AREAS) ? PROC0_NUM_SLOT_TABLE_AREAS : PROC1_NUM_SLOT_TABLE_AREAS;
+const uint32_t MAX_NUM_OF_SLOT_ENTRY_INFO = (PROC0_NUM_SLOT_ENTRY_INFO > PROC1_NUM_SLOT_ENTRY_INFO) ? PROC0_NUM_SLOT_ENTRY_INFO : PROC1_NUM_SLOT_ENTRY_INFO;
//each PHB lane size
const uint32_t NUM_OF_LANES_PER_PHB =
@@ -85,6 +92,60 @@ static_assert( NUM_OF_LANES_PER_PHB ==
sizeof(TARGETING::ATTR_PROC_PCIE_LANE_EQUALIZATION_GEN3_type)/2,
"no. of lanes per PHB should be 16");
+// HARD codes of slot map area and entry structs
+// TODO:SW398487 : Need to replace this with PNOR : HDAT partition consumption.
+// The below hardcoding is for temporary purpose but still valid values from mrw.
+
+hdatSlotMapArea_t hdatSlotMapAreas[MAX_NUM_OF_PROCS][MAX_NUM_OF_SLOT_TABLE_AREAS] = {
+{
+
+{ 1,0,0,0,0,0,0xFFFF,0,0,3,1,0,0,0,0,0,0,"SLOT3" },
+{ 2,0,1,0,0,0,0xFF00,0,0,0,0,0,0,0,0,0,0,0},
+{ 3,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+{ 4,0,2,0,0,0,0x00FF,0,0,0,0,0,0,0,0,0,0,0},
+{ 5,4,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+{ 6,0,3,0,0,0,0xFF00,0,0,1,1,0,0,0,0,0,0,"SLOT1" },
+{ 7,0,4,0,0,0,0x00F0,0,0,0,0,0,0,0,0,0,0,0},
+{ 8,7,4,1,0,0,0,0,0,0,2,0,0,0x10B5,8725,0,0,0},
+{ 9,8,4,2,0,0,0,0,0,0,0,0,4,0x10B5,8725,0,0,0 },
+{ 10,9,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,"GPU3" },
+{ 11,8,4,2,0,0,0,0,0,0,0,0,5,0x10B5,8725,0,0,0 },
+{ 12,11,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,"GPU4" },
+{ 13,0,5,0,0,0,0x000F,0,0,0,0,0,0,0,0,0,0,0},
+{ 14,13,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+
+},
+{
+{ 15,0,0,0,0,0,0xFFFF,0,0,2,1,0,0,0,0,0,0,"SLOT2" },
+{ 16,0,3,0,0,0,0xFF00,0,0,1,1,0,0,0,0,0,0,"SLOT1" },
+{ 17,0,4,0,0,0,0x00F0,0,0,0,1,0,0,0,0,0,0,"SLOT0" },
+{ 18,0,5,0,0,0,0x000F,0,0,0,0,0,0,0,0,0,0,0},
+{ 19,18,5,1,0,0,0,0,0,0,2,1,1,0x10B5,8725,0,0,0},
+{ 20,19,5,2,0,0,0,0,0,0,0,1,10,0x10B5,8725,0,0,0 },
+{ 21,20,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,"GPU0" },
+{ 22,19,5,2,0,0,0,0,0,0,0,1,11,0x10B5,8725,0,0,0 },
+{ 23,22,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,"GPU1" },
+{ 24,19,5,2,0,0,0,0,0,0,0,1,12,0x10B5,8725,0,0,0 },
+{ 25,24,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,"GPU2" },
+{ 26,19,5,2,0,0,0,0,0,0,0,1,13,0x10B5,8725,0,0,0 },
+{ 27,26,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,"GPU5" }
+}
+
+};
+
+hdatSlotEntryInfo_t hdatSlotMapEntries[MAX_NUM_OF_PROCS][MAX_NUM_OF_SLOT_ENTRY_INFO] = {
+{
+{ 1,0,0,0,0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0 },
+{ 6,0,0,0,0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0 }
+},
+{
+{ 15,0,0,0,0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0 },
+{ 16,0,0,0,0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0 },
+{ 17,0,0,0,0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0 }
+}
+};
+
+
/*******************************************************************************
* IO HUB constructor
*******************************************************************************/
@@ -99,7 +160,8 @@ HdatIoHubFru::HdatIoHubFru(errlHndl_t &o_errlHndl,
HDAT_IO_VERSION),
iv_hubStatus(0),iv_kwdSize(0),iv_maxHubs(HDAT_MAX_IO_CHIPS),
iv_maxDaughters(i_daughterCnt),iv_hubArraySize(0),iv_actDaughterCnt(0),
-iv_maxDaughterSize(0),iv_kwd(NULL),iv_hubArray(NULL),iv_daughterPtrs(NULL)
+iv_maxDaughterSize(0),iv_kwd(NULL),iv_hubArray(NULL),iv_daughterPtrs(NULL),
+iv_hdatSlotMapAreaPtr(NULL),iv_hdatSlotMapEntryInfoPtr(NULL)
{
HDAT_ENTER();
@@ -112,6 +174,8 @@ iv_maxDaughterSize(0),iv_kwd(NULL),iv_hubArray(NULL),iv_daughterPtrs(NULL)
iv_hubId.hdatReserved4 = 0;
iv_hubId.hdatReserved5 = 0;
iv_hubId.hdatReserved6 = 0;
+ iv_hdatSlotMapAreaArrayHdr = {0};
+ iv_hdatSlotMapEntryArrayHdr= {0};
iv_hubArrayHdr.hdatOffset = sizeof(hdatHDIFDataArray_t);
iv_hubArrayHdr.hdatArrayCnt = 0;
@@ -322,9 +386,32 @@ uint8_t * HdatIoHubFru::setIOHub(uint8_t * io_virt_addr,
{
HDAT_DBG("no daughter information to write");
}
+
+ HDAT_ADD_PAD(io_virt_addr);
+
+ if( iv_slotMapInfoObjs.size() > 0 )
+ {
+ for( auto &l_slotMapInfoEle : iv_slotMapInfoObjs)
+ {
+ io_virt_addr = l_slotMapInfoEle.setHdif(io_virt_addr);
+ memcpy(io_virt_addr, &iv_hdatSlotMapAreaArrayHdr, sizeof(hdatHDIFDataArray_t));
+ io_virt_addr += sizeof(hdatHDIFDataArray_t);
+ memcpy(io_virt_addr, iv_hdatSlotMapAreaPtr, sizeof(hdatSlotMapArea_t) * (iv_hdatSlotMapAreaArrayHdr.hdatArrayCnt));
+ io_virt_addr += sizeof(hdatSlotMapArea_t) * (iv_hdatSlotMapAreaArrayHdr.hdatArrayCnt);
+
+ HDAT_ADD_PAD(io_virt_addr);
+ memcpy(io_virt_addr, &iv_hdatSlotMapEntryArrayHdr, sizeof(hdatHDIFDataArray_t));
+ io_virt_addr += sizeof(hdatHDIFDataArray_t);
+ memcpy(io_virt_addr, iv_hdatSlotMapEntryInfoPtr, sizeof(hdatSlotEntryInfo_t) * (iv_hdatSlotMapEntryArrayHdr.hdatArrayCnt));
+ io_virt_addr += sizeof(hdatSlotEntryInfo_t) * (iv_hdatSlotMapEntryArrayHdr.hdatArrayCnt);
+
+ HDAT_ADD_PAD(io_virt_addr);
+ }
+ }
HDAT_DBG("exiting with virtual address=0x%016llX",
(uint64_t)io_virt_addr);
+ HDAT_ADD_PAD(io_virt_addr);
return io_virt_addr;
}
@@ -607,6 +694,87 @@ errlHndl_t HdatIoHubFru::addDaughterCard(uint32_t i_resourceId,
+errlHndl_t HdatIoHubFru::bldSlotMapInfoStruct(uint32_t i_numProc)
+{
+
+ errlHndl_t l_errlHndl = NULL;
+
+ HDAT_ENTER();
+ do{
+ const char HDAT_IOSLOT_STRUCT_NAME[] = "IOSLOT";
+ const uint16_t HDAT_SLOTMAP_INFO_VER = 0x0020;
+
+ iv_hdatSlotMapAreaPtr = reinterpret_cast<hdatSlotMapArea_t *>(calloc(
+ HDAT_MAX_SLOT_PER_HUB, sizeof(hdatSlotMapArea_t)));
+
+ iv_hdatSlotMapEntryInfoPtr =
+ reinterpret_cast<hdatSlotEntryInfo_t *>(calloc(
+ HDAT_MAX_SLOT_PER_HUB, sizeof(hdatSlotEntryInfo_t)));
+
+
+ HdatHdif *l_SlotMap = new HdatHdif(l_errlHndl,HDAT_IOSLOT_STRUCT_NAME,
+ HDAT_SLOT_MAP_LAST, 0, 0,
+ HDAT_SLOTMAP_INFO_VER);
+ if(l_errlHndl == NULL)
+ {
+
+ l_errlHndl = hdatGetSlotMapTableAreas(i_numProc);
+ if(l_errlHndl != NULL)
+ {
+ HDAT_ERR(" Slot Map Table Areas population failed");
+ break;
+ }
+
+ l_errlHndl = hdatGetSlotMapEntryInfos(i_numProc);
+ if(l_errlHndl != NULL)
+ {
+ HDAT_ERR(" Slot Map Entry Infos population failed");
+ break;
+ }
+
+ l_SlotMap->addData(HDAT_SLOT_MAP_AREA, sizeof(hdatHDIFDataArray_t)+
+ sizeof(hdatSlotMapArea_t) * iv_hdatSlotMapAreaArrayHdr.hdatArrayCnt);
+ l_SlotMap->align();
+ l_SlotMap->addData(HDAT_SLOT_MAP_ENTRY,sizeof(hdatHDIFDataArray_t)+
+ sizeof(hdatSlotEntryInfo_t) * iv_hdatSlotMapEntryArrayHdr.hdatArrayCnt);
+ l_SlotMap->align();
+ }
+ iv_slotMapInfoSize = l_SlotMap->size();
+ l_SlotMap->print();
+
+ this->addChild(HDAT_SLOT_MAP_INFO, iv_slotMapInfoSize ,1);
+ iv_slotMapInfoObjs.push_back(*l_SlotMap);
+ }while(0);
+ return(l_errlHndl);
+}
+
+
+
+errlHndl_t HdatIoHubFru::hdatGetSlotMapTableAreas(uint32_t i_numProc)
+{
+ errlHndl_t l_errlHndl = NULL;
+ iv_hdatSlotMapAreaArrayHdr = { sizeof(hdatHDIFDataArray_t),
+ (i_numProc == 0)? PROC0_NUM_SLOT_TABLE_AREAS:PROC1_NUM_SLOT_TABLE_AREAS,
+ sizeof(hdatSlotMapArea_t),
+ sizeof(hdatSlotMapArea_t) };
+ memcpy(iv_hdatSlotMapAreaPtr, hdatSlotMapAreas[i_numProc] , sizeof(hdatSlotMapArea_t)*iv_hdatSlotMapAreaArrayHdr.hdatArrayCnt);
+ return l_errlHndl;
+}
+
+errlHndl_t HdatIoHubFru::hdatGetSlotMapEntryInfos(uint32_t i_numProc)
+{
+ errlHndl_t l_errlHndl = NULL;
+ iv_hdatSlotMapEntryArrayHdr = { sizeof(hdatHDIFDataArray_t),
+ (i_numProc == 0)?PROC0_NUM_SLOT_ENTRY_INFO:PROC1_NUM_SLOT_ENTRY_INFO ,
+ sizeof(hdatSlotEntryInfo_t),
+ sizeof(hdatSlotEntryInfo_t) };
+ memcpy(iv_hdatSlotMapEntryInfoPtr, hdatSlotMapEntries[i_numProc], sizeof(hdatSlotEntryInfo_t)*iv_hdatSlotMapEntryArrayHdr.hdatArrayCnt);
+ return l_errlHndl;
+}
+
+
+
+
/******************************************************************************/
// hdatLoadIoData
/******************************************************************************/
@@ -618,7 +786,7 @@ errlHndl_t hdatLoadIoData(const hdatMsAddr_t &i_msAddr,
errlHndl_t l_err = NULL;
uint32_t l_size = 0;
- uint64_t l_totKwdSize = 0;
+ uint64_t l_totKwdSize = 0 , l_totalSlotMapSize = 0;
IO_MAP l_iomap;
o_size = 0;
@@ -830,7 +998,18 @@ errlHndl_t hdatLoadIoData(const hdatMsAddr_t &i_msAddr,
break;
}
- HDAT_DBG("fruData.bldDaughterStruct done, will insert to the map");
+ HDAT_DBG("fruData.bldDaughterStruct done");
+
+ //build the slot map info structure
+ l_err = fruData->bldSlotMapInfoStruct(l_numProcs);
+
+ if ( l_err )
+ {
+ HDAT_ERR("error in building Slot map info structure");
+ break;
+ }
+
+ HDAT_DBG("fruData.bldSlotMapInfoStruct done, will insert to the map");
//insert the fru data to the map
l_iomap.insert(std::pair<uint32_t,HdatIoHubFru*>
@@ -839,6 +1018,9 @@ errlHndl_t hdatLoadIoData(const hdatMsAddr_t &i_msAddr,
l_totKwdSize = fruData->getTotalIoKwdSize();
HDAT_DBG("got l_totKwdSize=%x",l_totKwdSize);
+
+ l_totalSlotMapSize = fruData->iv_slotMapInfoObjs.size() *
+ fruData->iv_slotMapInfoSize;
}//end for loop
@@ -860,7 +1042,7 @@ errlHndl_t hdatLoadIoData(const hdatMsAddr_t &i_msAddr,
}
uint64_t l_totalsize = (HDAT_MAX_IO_CHIPS * sizeof(hdatHubEntry_t)) +
(HDAT_PARENT_LAST * sizeof(hdatHDIFDataHdr_t))+
- l_childPtrSize;
+ l_childPtrSize + l_totalSlotMapSize;
uint64_t i_base_addr_down = ALIGN_PAGE_DOWN(i_base_addr);
diff --git a/src/usr/hdat/hdatiohub.H b/src/usr/hdat/hdatiohub.H
index 642667b85..14c3a8524 100755
--- a/src/usr/hdat/hdatiohub.H
+++ b/src/usr/hdat/hdatiohub.H
@@ -62,6 +62,8 @@ const uint16_t HDAT_VPD_VERSION = 0x0020;
const uint16_t HDAT_IO_VERSION = 0x7B;
const uint32_t HDAT_MAX_IO_CHIPS = 10;
+const uint32_t HDAT_MAX_SLOT_PER_HUB = 32;
+
/*---------------------------------------------------------------------------*/
/* Type definitions */
@@ -127,6 +129,60 @@ struct hdatHubEntry_t
}
} __attribute__ ((packed));
+struct hdatSlotMapArea_t
+{
+ uint16_t hdatEntryId;
+ uint16_t hdatParentEntryId;
+ uint8_t hdatPHBId;
+ uint8_t hdatEntryType;
+ uint8_t hdatLaneSwapCnfg;
+ uint8_t hdatReserved1;
+ uint16_t hdatLaneMask;
+ uint16_t hdatLaneReversal;
+ uint16_t hdatSLCAIndx;
+ uint16_t hdatSlotIndx;
+ uint32_t hdatEntryFeatures;
+ uint8_t hdatStationId;
+ uint8_t hdatPortNum;
+ uint32_t hdatSwitchVendorId;
+ uint32_t hdatSwitchDeviceId;
+ uint32_t hdatSubSysVendorId;
+ uint32_t hdatSubSysDeviceId;
+ char hdatSlotName[8];
+} __attribute__ ((packed));
+
+
+struct hdatSlotEntryInfo_t
+{
+ uint16_t hdatEntryId;
+ uint8_t hdatMGCLoadSource;
+ uint8_t hdatHddwOrder;
+ uint16_t hdat32MmioSizeInMB;
+ uint16_t hdat64MmioSizeInGB;
+ uint16_t hdat32DMASizeInGB;
+ uint16_t hdat64DMASizeInGB;
+ uint8_t hdatSlotPwrCtrlType;
+ uint8_t hdatPresCtrlType;
+ uint8_t hdatPERSTCtrlType;
+ uint8_t hdatPERSTCtrlGPIOPin;
+ uint16_t hdatMAxPowrSupported;
+ uint32_t hdatSlotCaps;
+ uint16_t hdatMSI;
+ uint32_t hdatI2cIdSlotPwrCtrl;
+ uint32_t hdatI2cSlotPwrPgood;
+ uint32_t hdatI2cCableCardPres;
+ uint32_t hdatI2cCableCardSlotEnable;
+ uint32_t hdatI2cMexFPGA;
+} __attribute__ ((packed));
+
+enum hdatSlotMapDataPtrs
+{
+ HDAT_SLOT_MAP_AREA = 0,
+ HDAT_SLOT_MAP_ENTRY = 1,
+ HDAT_SLOT_MAP_RSVD1 = 2,
+ HDAT_SLOT_MAP_RSVD2 = 3,
+ HDAT_SLOT_MAP_LAST = 4
+};
/** @enum hdatDataPtrs
@@ -151,8 +207,9 @@ enum hdatioDataPtrs
enum hdatioChildPtrs
{
HDAT_DAUGHTER_CARD = 0,
- HDAT_CHILD_RESERVED1 = 1,
- HDAT_CHILD_LAST = 2
+ HDAT_SLOT_MAP_INFO = 1,
+ HDAT_CHILD_RESERVED1 = 2,
+ HDAT_CHILD_LAST = 3
};
@@ -394,6 +451,26 @@ public:
errlHndl_t bldDaughterStruct( const TARGETING::Target * i_target,
uint32_t i_index );
+ /**
+ * @brief Build the hypervisor data area structres for Slot Map structure.
+ *
+ * Each PCIe slot connected to I/O hub will have a datastructure built
+ *
+ * @pre None
+ *
+ * @param i_target - input parameter - TARGET value of IO Hub ( proc)
+ * @param i_virtAddr - input parameter - mainstore virtual address
+ *
+ * @return A null error log handle if successful, else the return code pointed
+ * to by errlHndl_t contains one of:
+ *
+ */
+
+ errlHndl_t bldSlotMapInfoStruct(uint32_t i_numProc);
+
+
+ errlHndl_t hdatGetSlotMapTableAreas(uint32_t i_numProc);
+ errlHndl_t hdatGetSlotMapEntryInfos(uint32_t i_numProc);
/*
* @brief fetches all the daughter card information for a proc when the
@@ -491,6 +568,12 @@ public:
hdatHDIFDataArray_t iv_hubArrayHdr;
hdatHubEntry_t *iv_hubArray;
HdatVpd **iv_daughterPtrs;
+ std::vector<HdatHdif> iv_slotMapInfoObjs;
+ uint32_t iv_slotMapInfoSize;
+ hdatHDIFDataArray_t iv_hdatSlotMapAreaArrayHdr;
+ hdatHDIFDataArray_t iv_hdatSlotMapEntryArrayHdr;
+ hdatSlotMapArea_t *iv_hdatSlotMapAreaPtr;
+ hdatSlotEntryInfo_t *iv_hdatSlotMapEntryInfoPtr;
}; // end of HdatIoHubFru class
diff --git a/src/usr/hdat/hdatpcrd.C b/src/usr/hdat/hdatpcrd.C
index 4033e32f0..29794ad60 100644
--- a/src/usr/hdat/hdatpcrd.C
+++ b/src/usr/hdat/hdatpcrd.C
@@ -129,7 +129,10 @@ static errlHndl_t hdatSetPcrdHdrs(hdatSpPcrd_t *i_pcrd)
i_pcrd->hdatPcrdIntData[HDAT_PCRD_DA_PNOR].hdatOffset = 0;
i_pcrd->hdatPcrdIntData[HDAT_PCRD_DA_PNOR].hdatSize =
- sizeof(hdatPcrdPnor_t);
+ sizeof(hdatPcrdPnor_t);
+ i_pcrd->hdatPcrdIntData[HDAT_PCRD_DA_SMP].hdatOffset = 0;
+ i_pcrd->hdatPcrdIntData[HDAT_PCRD_DA_SMP].hdatSize = 0;
+
return l_errlHndl;
}
@@ -144,7 +147,9 @@ HdatPcrd::HdatPcrd(errlHndl_t &o_errlHndl, const hdatMsAddr_t &i_msAddr)
iv_numPcrdEntries = HDAT_NUM_P7_PCRD_ENTRIES;
iv_spPcrdEntrySize = sizeof(hdatSpPcrd_t) + HDAT_FULL_MVPD_SIZE +
sizeof(hdatHDIFVersionedDataArray_t) + ((sizeof(hdatI2cData_t)
- * HDAT_PCRD_MAX_I2C_DEV));
+ * HDAT_PCRD_MAX_I2C_DEV))
+ + sizeof(hdatHDIFDataArray_t)
+ + (sizeof(hdatSMPLinkInfo_t) * HDAT_PCRD_MAX_SMP_LINK);
// Allocate space for each CHIP -- will use max amount to start
uint64_t l_base_addr = ((uint64_t) i_msAddr.hi << 32) | i_msAddr.lo;
@@ -562,6 +567,54 @@ errlHndl_t HdatPcrd::hdatLoadPcrd(uint32_t &o_size, uint32_t &o_count)
// structs should be of same size
this->iv_spPcrd->hdatHdr.hdatSize += sizeof(hdatPcrdPnor_t);
+ // Setting SMP Link info
+ uint32_t l_pcrdSMPTotalSize = 0;
+
+ hdatHDIFDataArray_t *l_SMPInfoFullPcrdHdrPtr = NULL;
+ l_SMPInfoFullPcrdHdrPtr = reinterpret_cast<hdatHDIFDataArray_t *>
+ ((uint8_t*)l_pnor + sizeof(hdatPcrdPnor_t));
+
+ // Need to get SMP Link info data correctly
+ std::vector<hdatSMPLinkInfo_t> l_SMPInfoEntries;
+
+ hdatGetSMPLinkInfo(l_pProcTarget, l_SMPInfoEntries);
+
+ l_pcrdSMPTotalSize = sizeof(hdatHDIFDataArray_t) +
+ (sizeof(hdatSMPLinkInfo_t) * l_SMPInfoEntries.size());
+
+ HDAT_INF("pcrdSMPNumEntries=0x%x, l_pcrdSMPTotalSize=0x%x",
+ l_SMPInfoEntries.size(), l_pcrdSMPTotalSize);
+ l_SMPInfoFullPcrdHdrPtr->hdatOffset = 0x0010; // All array entries start right after header which is of 4 word size
+ l_SMPInfoFullPcrdHdrPtr->hdatArrayCnt =
+ l_SMPInfoEntries.size();
+ l_SMPInfoFullPcrdHdrPtr->hdatAllocSize =
+ sizeof(hdatSMPLinkInfo_t);
+ l_SMPInfoFullPcrdHdrPtr->hdatActSize =
+ sizeof(hdatSMPLinkInfo_t);
+
+
+ hdatSMPLinkInfo_t *l_SMPInfoFullPcrdDataPtr = NULL;
+ l_SMPInfoFullPcrdDataPtr = reinterpret_cast<hdatSMPLinkInfo_t *>
+ ((uint8_t*)l_SMPInfoFullPcrdHdrPtr + sizeof(hdatHDIFDataArray_t));
+
+ if ( l_SMPInfoEntries.size() != 0 )
+ {
+ //copy data from vector to data ptr
+ std::copy(l_SMPInfoEntries.begin(),
+ l_SMPInfoEntries.end(), l_SMPInfoFullPcrdDataPtr);
+ }
+ else
+ {
+ HDAT_INF("Empty SMP Link info vector : Size=%d",
+ l_SMPInfoEntries.size());
+ }
+ this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_SMP].hdatOffset =
+ this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_PNOR].hdatOffset +
+ sizeof(hdatPcrdPnor_t);
+ this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_SMP].hdatSize = l_pcrdSMPTotalSize;
+ this->iv_spPcrd->hdatHdr.hdatSize +=
+ sizeof(hdatHDIFDataArray_t) + (sizeof(hdatSMPLinkInfo_t) * HDAT_PCRD_MAX_SMP_LINK);
+
if( NULL != l_errl)
{
break;
diff --git a/src/usr/hdat/hdatpcrd.H b/src/usr/hdat/hdatpcrd.H
index 3d5ef0bcd..e8b4f6428 100644
--- a/src/usr/hdat/hdatpcrd.H
+++ b/src/usr/hdat/hdatpcrd.H
@@ -60,6 +60,7 @@ const char HDAT_PCRD_STRUCT_NAME[7] = "SPPCRD";
//Max number of I2c devices for any given proc
#define HDAT_PCRD_MAX_I2C_DEV 64
+#define HDAT_PCRD_MAX_SMP_LINK 12
/** @enum hdatDataPtrs
* Enumeration which defines the data sections of the PCRD
@@ -74,8 +75,9 @@ enum hdatPcrdDataPtrs
HDAT_PCRD_DA_CHIP_VPD = 4,
HDAT_PCRD_DA_HOST_I2C = 5,
HDAT_PCRD_DA_PNOR = 6,
- HDAT_PCRD_DA_CNT = 7,
- HDAT_PCRD_DA_LAST = 8,
+ HDAT_PCRD_DA_SMP = 7,
+ HDAT_PCRD_DA_CNT = 8,
+ HDAT_PCRD_DA_LAST = 9,
};
/*----------------------------------------------------------------------------*/
diff --git a/src/usr/hdat/hdatutil.C b/src/usr/hdat/hdatutil.C
index f13a4e89e..abfa1834a 100644
--- a/src/usr/hdat/hdatutil.C
+++ b/src/usr/hdat/hdatutil.C
@@ -36,6 +36,48 @@ namespace HDAT
{
extern trace_desc_t *g_trac_hdat;
+// HARD codes of sequoia and redbud GPU configurations for SMP link struct
+// TODO:SW398487 : Need to replace this with PNOR : HDAT partition consumption.
+// The below hardcoding is for temporary purpose but still valid values from mrw.
+
+// SEQUOIA
+const hdatSMPLinkInfo_t l_hdatSMPLinkInfoProc0_6gpucfg[] = {
+ {0,0x01,0x00,0xF1E00000,21,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {1,0x01,0x01,0x07187000,21,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {2,0x01,0x02,0x00078F00,23,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {3,0x01,0x09,0xF1E00000,25,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {4,0x01,0x0A,0x07187000,25,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {5,0x01,0x0B,0x00078F00,23,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF}
+};
+const hdatSMPLinkInfo_t l_hdatSMPLinkInfoProc1_6gpucfg[] = {
+ {0,0x01,0x00,0xF1E00000,10,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {1,0x01,0x01,0x07187000,10,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {2,0x01,0x02,0x00078F00,12,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {3,0x01,0x09,0xF1E00000,27,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {4,0x01,0x0A,0x07187000,27,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {5,0x01,0x0B,0x00078F00,12,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF}
+};
+
+// REDBUD
+const hdatSMPLinkInfo_t l_hdatSMPLinkInfoProc0_4gpucfg[] = {
+ {0,0x01,0x00,0xF1E00000,21,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {1,0x01,0x01,0x07187000,21,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {2,0x01,0x02,0x00078F00,21,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {3,0x01,0x09,0xF1E00000,23,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {4,0x01,0x0A,0x07187000,23,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {5,0x01,0x0B,0x00078F00,23,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF}
+};
+const hdatSMPLinkInfo_t l_hdatSMPLinkInfoProc1_4gpucfg[] = {
+ {0,0x01,0x00,0xF1E00000,25,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {1,0x01,0x01,0x07187000,25,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {2,0x01,0x02,0x00078F00,25,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {3,0x01,0x09,0xF1E00000,10,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {4,0x01,0x0A,0x07187000,10,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF},
+ {5,0x01,0x0B,0x00078F00,10,0xFFFF,0xFF,0x00,0xFF,0xFF,0xFF}
+};
+
+
+
/*****************************************************************************n
* hdatBldErrLog
*******************************************************************************/
@@ -1814,5 +1856,141 @@ void hdatGetI2cDeviceInfo(
}
+/*******************************************************************************
+ * hdatGetSMPLinkInfo
+ *
+ * @brief Routine returns the Host SMP Link info entries
+ *
+ * @pre None
+ *
+ * @post None
+ *
+ * @param[in] i_pTarget
+ * The SMP link master target handle
+ * @param[out] o_SMPLinkEntries
+ * The host SMP Link info entries
+ *
+ * @return void
+ *
+*******************************************************************************/
+
+
+void hdatGetSMPLinkInfo(TARGETING::Target* i_pTarget,
+ std::vector<hdatSMPLinkInfo_t>&o_SMPLinkEntries)
+{
+ HDAT_ENTER();
+
+ errlHndl_t l_err = NULL;
+ uint8_t *l_NVKwd = NULL;
+ PVPD::pvpdRecord l_Record = PVPD::VNDR;
+ PVPD::pvpdKeyword l_KeyWord = PVPD::NV;
+ size_t l_nvKwdSize = 0;
+
+ TARGETING::TargetHandleList l_targList;
+ PredicateCTM predNode(TARGETING::CLASS_ENC, TARGETING::TYPE_NODE);
+ PredicateHwas predFunctional;
+ predFunctional.functional(true);
+ PredicatePostfixExpr nodeCheckExpr;
+ nodeCheckExpr.push(&predNode).push(&predFunctional).And();
+
+ targetService().getAssociated(l_targList, i_pTarget,
+ TargetService::PARENT, TargetService::IMMEDIATE,
+ &nodeCheckExpr);
+ TARGETING::Target* l_target = l_targList[0];
+
+ l_err = deviceRead(l_target,NULL,l_nvKwdSize,
+ DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
+ if(l_err == NULL)
+ {
+ if(l_nvKwdSize == sizeof(hdatNVKwdStruct_t))
+ {
+ uint8_t l_kwd[l_nvKwdSize] = {0};
+ l_err = deviceRead(l_target,l_kwd,l_nvKwdSize,
+ DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
+
+ if(l_err == NULL)
+ {
+ l_NVKwd = new uint8_t[sizeof(hdatNVKwdStruct_t)];
+ memcpy(l_NVKwd, l_kwd, sizeof(hdatNVKwdStruct_t));
+ }
+ else
+ {
+ HDAT_ERR(" Device Read for NV keyword errored out ");
+ ERRORLOG::errlCommit(l_err,HDAT_COMP_ID);
+ }
+ }
+ else
+ {
+ HDAT_ERR("Returned length for NV keyword is 0x%x which is not 0x%x",
+ l_nvKwdSize,sizeof(hdatNVKwdStruct_t));
+ }
+ }
+ else
+ {
+ HDAT_ERR("deviceRead failed for NV keyword VNDR record");
+ }
+
+ const hdatSMPLinkInfo_t *l_smpLinkInfoPtr = NULL;
+ uint32_t l_smpLinkInfoSize = 0;
+
+ if(l_NVKwd != NULL)
+ {
+ if((reinterpret_cast<hdatNVKwdStruct_t *>(l_NVKwd)->magic == HDAT_NV_KWD_MAGIC_WRD)
+ &&(reinterpret_cast<hdatNVKwdStruct_t *>(l_NVKwd)->version == 0x01))
+ {
+ if(reinterpret_cast<hdatNVKwdStruct_t *>(l_NVKwd)->config == HDAT_REDBUD_NV_CNFG)
+ {
+ if(i_pTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>() == 0)
+ {
+ l_smpLinkInfoPtr = l_hdatSMPLinkInfoProc0_4gpucfg;
+ l_smpLinkInfoSize = sizeof(l_hdatSMPLinkInfoProc0_4gpucfg)/sizeof(hdatSMPLinkInfo_t);
+ }
+ else
+ {
+ l_smpLinkInfoPtr = l_hdatSMPLinkInfoProc1_4gpucfg;
+ l_smpLinkInfoSize = sizeof(l_hdatSMPLinkInfoProc1_4gpucfg)/sizeof(hdatSMPLinkInfo_t);
+ }
+ }
+ else if(reinterpret_cast<hdatNVKwdStruct_t *>(l_NVKwd)->config == HDAT_SEQUOIA_NV_CNFG)
+ {
+ if(i_pTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>() == 0)
+ {
+ l_smpLinkInfoPtr = l_hdatSMPLinkInfoProc0_6gpucfg;
+ l_smpLinkInfoSize = sizeof(l_hdatSMPLinkInfoProc0_6gpucfg)/sizeof(hdatSMPLinkInfo_t);
+ }
+ else
+ {
+ l_smpLinkInfoPtr = l_hdatSMPLinkInfoProc1_6gpucfg;
+ l_smpLinkInfoSize = sizeof(l_hdatSMPLinkInfoProc1_6gpucfg)/sizeof(hdatSMPLinkInfo_t);
+ }
+ }
+ }
+ else
+ {
+ HDAT_ERR(" Unknown config : NV KWD Magic = 0X%8X, Version = 0x%x");
+ }
+ }
+
+ for( uint32_t l_count = 0; l_count < l_smpLinkInfoSize ; l_count++)
+ {
+ hdatSMPLinkInfo_t l_hdatSMPLinkInfo;
+ memcpy(&l_hdatSMPLinkInfo, &l_smpLinkInfoPtr[l_count], sizeof(hdatSMPLinkInfo_t));
+ o_SMPLinkEntries.push_back(l_hdatSMPLinkInfo);
+ }
+ if(l_NVKwd != NULL)
+ {
+ delete l_NVKwd;
+ l_NVKwd = NULL;
+ }
+ if(l_err != NULL)
+ {
+ delete l_err;
+ l_err = NULL;
+ }
+
+ HDAT_EXIT();
+}
+
+
} //namespace HDAT
diff --git a/src/usr/hdat/hdatutil.H b/src/usr/hdat/hdatutil.H
index 1e730aeba..109921f3a 100755
--- a/src/usr/hdat/hdatutil.H
+++ b/src/usr/hdat/hdatutil.H
@@ -95,6 +95,9 @@ const uint16_t HDAT_VERSION3 = 3;
#define UINT64_LOW(u) (u & 0x00000000FFFFFFFF)
+#define HDAT_ADD_PAD(x) x += (16 - ((uint64_t)x % 16))
+
+#define HDAT_NV_KWD_MAGIC_WRD 0x4E563030 // "NV00"
namespace HDAT
{
@@ -124,6 +127,45 @@ struct hdatI2cData_t
}__attribute__ ((packed));
+/* @brief Defines the SMP Link info */
+struct hdatSMPLinkInfo_t
+{
+ uint32_t hdatSMPLinkID;
+ uint32_t hdatSMPLinkUsage;
+ uint32_t hdatSMPLinkBrickID;
+ uint32_t hdatSMPLinkLaneMask;
+ uint16_t hdatSMPLinkPCISlotIndex;
+ uint16_t hdatSMPLinkPCISlotSideBand;
+ uint16_t hdatSMPLinkSLCAIndex;
+ uint16_t hdatReserved1;
+ uint32_t hdatSMPLinkI2cLinkId;
+ uint32_t hdatSMPLinkI2cLinkIdPres;
+ uint32_t hdatSMPLinkI2cLinkIdMicro;
+
+}__attribute__ ((packed));
+
+/** NV Keyword header struct */
+typedef struct{
+ uint32_t magic; // = "NV00"
+ uint8_t version; // Version of the structure = 0x01 start
+ uint8_t config; // Configuration specifier : redbud=0x01,sequoia=0x02
+ uint8_t reserved[249]; // keyword is 255 bytes long
+}hdatNVKwdStruct_t;
+
+enum hdatSMPLinkUsage
+{
+ HDAT_SMP_LINK_USAGE_SMP = 0,
+ HDAT_SMP_LINK_USAGE_NATIVE_GPU = 1,
+ HDAT_SMP_LINK_USAGE_EXT_IODRW = 2,
+ HDAT_SMP_LINK_USAGE_GPU_TO_GPU = 3,
+ HDAT_SMP_LINK_USAGE_UNKNOWN = 0xFFFF,
+};
+enum hdatWitherspoonNVCnfg
+{
+ HDAT_REDBUD_NV_CNFG = 1,
+ HDAT_SEQUOIA_NV_CNFG = 2,
+};
+
/**
* @brief Create/Build an Error log and add HADT component trace
@@ -506,6 +548,27 @@ errlHndl_t hdatGetFullEepromVpd ( TARGETING::Target * i_target,
void hdatGetI2cDeviceInfo(TARGETING::Target* i_pTarget,
std::vector<hdatI2cData_t>&o_i2cDevEntries);
+/*******************************************************************************
+ * hdatGetSMPLinkInfo
+ *
+ * @brief Routine returns the Host SMP Link info entries
+ *
+ * @pre None
+ *
+ * @post None
+ *
+ * @param[in] i_pTarget
+ * The SMP Link master target handle
+ * @param[out] o_SMPLinkEntries
+ * The host SMP Link entries
+ *
+ * @return void
+ *
+*******************************************************************************/
+void hdatGetSMPLinkInfo(TARGETING::Target* i_pTarget,
+ std::vector<hdatSMPLinkInfo_t>&o_SMPLinkEntries);
+
+
};// end namespace
OpenPOWER on IntegriCloud