diff options
author | nagurram-in <nagendra.g@in.ibm.com> | 2017-08-07 07:00:32 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-08-22 10:05:44 -0400 |
commit | 6a8caef78b3bd678fa9412c9734f23bc523ad37e (patch) | |
tree | 8595624325051db04e4c8de59db2971b4c70a6bc /src/usr/hdat | |
parent | 818acb95a2dc8ff8e94c652e0964f013c1bf34cb (diff) | |
download | talos-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.C | 190 | ||||
-rwxr-xr-x | src/usr/hdat/hdatiohub.H | 87 | ||||
-rw-r--r-- | src/usr/hdat/hdatpcrd.C | 57 | ||||
-rw-r--r-- | src/usr/hdat/hdatpcrd.H | 6 | ||||
-rw-r--r-- | src/usr/hdat/hdatutil.C | 178 | ||||
-rwxr-xr-x | src/usr/hdat/hdatutil.H | 63 |
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 |