From f560231a9e837b40fa1ad5f39d5be981390e5482 Mon Sep 17 00:00:00 2001 From: Raja Das Date: Mon, 24 Sep 2018 01:48:04 -0500 Subject: Optimized the processor dump structure between SBE and Hostboot -- Update SPR and GPR type valur to match hdat spec Change-Id: Ie8399dc9801b1e9381ba045ad871159d6a09e92a Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66510 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Srikantha S. Meesala Reviewed-by: RAJA DAS --- src/sbefw/app/power/sbearchregdump.C | 348 +++++++++++++++++++++++------------ src/sbefw/core/sbeHostMsg.H | 69 ++++++- 2 files changed, 288 insertions(+), 129 deletions(-) diff --git a/src/sbefw/app/power/sbearchregdump.C b/src/sbefw/app/power/sbearchregdump.C index 2b52a6c1..e07bb19f 100644 --- a/src/sbefw/app/power/sbearchregdump.C +++ b/src/sbefw/app/power/sbearchregdump.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2018 */ +/* Contributors Listed Below - COPYRIGHT 2018,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -47,12 +47,16 @@ using namespace fapi2; #define SPR_LIST_SIZE 63 #define GPR_LIST_SIZE 32 +#define GPR_REG_TYPE 0x1 +#define SPR_REG_TYPE 0x2 // This is defined in Hostboot src/include/usr/sbeio/sbeioif.H, this is just a // copy, so that SBE refers to the same count. #define STASH_KEY_CNT_FOR_ARCH_DUMP_ADDR 0x4 #define SSHSRC_STOP_GATED_BIT 0 +#define INVALID_CORE_STATE 0x1; +#define VALID_CORE_STATE_FOR_RAM 0x0; /////////////////////////////////////////////////////////////////////// // @brief sbeFetchRegDumpAddrFromStash // @@ -75,6 +79,86 @@ uint64_t sbeFetchRegDumpAddrFromStash(void) return addr; #undef SBE_FUNC } + +ReturnCode checkCoreStateForRam( + const fapi2::Target& i_coreTgt, + bool & o_isRamming, + uint8_t & o_coreState ) +{ + #define SBE_FUNC " checkCoreStateForRam " + SBE_ENTER(SBE_FUNC); + + ReturnCode fapiRc = FAPI2_RC_SUCCESS; + uint8_t chipUnitNum = 0; + o_isRamming = false; + o_coreState = VALID_CORE_STATE_FOR_RAM; + FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_coreTgt, chipUnitNum); + + do + { + fapi2::buffer ppm_ssh_buf = 0; + fapiRc = getscom_abs_wrap (&i_coreTgt, C_PPM_SSHSRC, &ppm_ssh_buf()); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC "Failed to read SSHSRC for Core[%d]", + chipUnitNum); + break; + } + //Check for Stop-gated (to check if corestate is valid) + if (ppm_ssh_buf.getBit() == 1) + { + // CoreState may be 2/4/5/11 + ppm_ssh_buf.extractToRight(o_coreState, 8, 4); + // StopState Enabled, skip ramming, + SBE_INFO(SBE_FUNC "StopGated Set for Core [%d] StopState[%d], " + "no ramming", chipUnitNum, o_coreState); + break; + } + + //Not Stop Gated + // CoreState may be 0/1, we need to identify which one. + // Only for coreState 0, we need to enable ramming. + // Double check the core isn't in stop 1 + auto exTgt = i_coreTgt.getParent(); + fapi2::buffer sisr_buf = 0; + fapiRc = getscom_abs_wrap (&exTgt, EX_CME_LCL_SISR_SCOM, &sisr_buf()); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC "Failed to read SISR for Core[%d]", + chipUnitNum); + break; + } + uint32_t pos = chipUnitNum % 2; + if (pos == 0 && sisr_buf.getBit()) + { + sisr_buf.extractToRight(o_coreState, + EX_CME_LCL_SISR_PM_STATE_C0, + EX_CME_LCL_SISR_PM_STATE_C0_LEN); + } + if (pos == 1 && sisr_buf.getBit()) + { + sisr_buf.extractToRight(o_coreState, + EX_CME_LCL_SISR_PM_STATE_C1, + EX_CME_LCL_SISR_PM_STATE_C1_LEN); + } + if(o_coreState == 0) + { + // Enable ramming for core state 0 + o_isRamming = true; + SBE_INFO(SBE_FUNC "StopGated not set for Core[%d] StopState" + " [%d], so yes ramming", chipUnitNum,o_coreState); + } + else + { + SBE_INFO(SBE_FUNC "StopGated set for Core[%d] StopState" + " [%d], so no ramming", chipUnitNum, o_coreState); + } + }while(0); + + SBE_EXIT(SBE_FUNC); + return fapiRc; + #undef SBE_FUNC +} /////////////////////////////////////////////////////////////////////// // @brief sbeDumpArchRegs Dump out the architected registers // @@ -85,8 +169,9 @@ ReturnCode sbeDumpArchRegs() SBE_ENTER(SBE_FUNC); ReturnCode fapiRc = FAPI2_RC_SUCCESS; uint64_t dumpAddr = 0; - sbeArchRegDumpFormat_t dump = {}; - sbe_pir_t pir = {}; + sbeArchRegDumpProcHdr_t dumpProcHdr = {}; + sbeArchRegDumpThreadHdr_t dumpThreadHdr = {}; + sbeArchRegDumpEntries_t dumpRegData = {}; // Combined list of SPRs GPRs static const uint16_t SPR_GPR_list[] = { @@ -127,184 +212,207 @@ ReturnCode sbeDumpArchRegs() SBE_MEM_ACCESS_WRITE, sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES); - // Go for each core under this Proc + + //Build the Proc specific header and send to the host + dumpProcHdr.ownerId = 0; //Indicates SBE + dumpProcHdr.version = DUMP_STRUCT_VERSION_ID; + dumpProcHdr.core_cnt = + procTgt.getChildren().size(); + dumpProcHdr.thread_count = (dumpProcHdr.core_cnt * SMT4_THREAD_MAX); + dumpProcHdr.reg_cnt = (sizeof(SPR_GPR_list)/sizeof(uint16_t)); + + + fapiRc = PBAInterface.accessWithBuffer(&dumpProcHdr, + sizeof(dumpProcHdr),false); + if(fapiRc != fapi2::FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "Failed to write Proc header to hostboot"); + break; + } + + //Interate through all the Cores under the Proc chips for(auto &coreTgt : procTgt.getChildren()) { bool doRamming = false; + uint8_t coreState = 0; uint8_t chipUnitNum = 0; uint8_t procGrpId = 0; uint8_t procChipId = 0; + // Required for PIR calculation FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, coreTgt, chipUnitNum); FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_GROUP_ID, procTgt, procGrpId); - FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_CHIP_ID, procTgt, procChipId); - - // Fetch the core state - uint8_t coreState = 0; - fapi2::buffer ppm_ssh_buf = 0; - fapiRc = getscom_abs_wrap (&coreTgt, C_PPM_SSHSRC, &ppm_ssh_buf()); + FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_CHIP_ID, procTgt,procChipId); + fapiRc = checkCoreStateForRam(coreTgt, doRamming, coreState); if( fapiRc != FAPI2_RC_SUCCESS ) { - SBE_ERROR(SBE_FUNC "Failed to read SSHSRC for Core[%d]", + SBE_ERROR(SBE_FUNC "Failed in checkCoreStateForRam Core[%d]", chipUnitNum); - continue; - } - //Check for Stop-gated (to check if corestate is valid) - if (ppm_ssh_buf.getBit() == 1) - { - // CoreState may be 2/4/5/11 - ppm_ssh_buf.extractToRight(coreState, 8, 4); - // StopState Enabled, skip ramming, but need to send out - // holes inplace of register/values. - SBE_INFO(SBE_FUNC "StopGated Set for Core [%d] StopState[%d], " - "no ramming", chipUnitNum, coreState); - } - else // not stop gated - { - // CoreState may be 0/1, we need to identify which one. - // Only for coreState 0, we need to enable ramming. - // Double check the core isn't in stop 1 - auto exTgt = coreTgt.getParent(); - fapi2::buffer sisr_buf = 0; - fapiRc = getscom_abs_wrap (&exTgt, EX_CME_LCL_SISR_SCOM, &sisr_buf()); - if( fapiRc != FAPI2_RC_SUCCESS ) - { - SBE_ERROR(SBE_FUNC "Failed to read SISR for Core[%d]", - chipUnitNum); - continue; - } - uint32_t pos = chipUnitNum % 2; - if (pos == 0 && sisr_buf.getBit()) - { - sisr_buf.extractToRight(coreState, - EX_CME_LCL_SISR_PM_STATE_C0, - EX_CME_LCL_SISR_PM_STATE_C0_LEN); - } - if (pos == 1 && sisr_buf.getBit()) - { - sisr_buf.extractToRight(coreState, - EX_CME_LCL_SISR_PM_STATE_C1, - EX_CME_LCL_SISR_PM_STATE_C1_LEN); - } - if(coreState == 0) - { - // Enable ramming for core state 0 - doRamming = true; - SBE_INFO(SBE_FUNC "StopGated not set for Core[%d] StopState" - " [%d], so yes ramming", chipUnitNum); - } - else - { - SBE_INFO(SBE_FUNC "StopGated not set for Core[%d] StopState" - " [%d], so no ramming", chipUnitNum, coreState); - } + //Mark the coreState to be bad and disable ramming. + coreState = INVALID_CORE_STATE; + doRamming = false; } - for(uint8_t thread = SMT4_THREAD0; thread < SMT4_THREAD_MAX; thread++) + for(uint8_t thread = SMT4_THREAD0;thread < SMT4_THREAD_MAX;thread++) { + //Build the thread header for each thread related to the core. + dumpThreadHdr.pir.procGrpId = procGrpId; + dumpThreadHdr.pir.procChipId = procChipId; + dumpThreadHdr.pir.chipUnitNum = chipUnitNum; + dumpThreadHdr.pir.thread = thread; + dumpThreadHdr.coreState = coreState; + + + //Check if ram setup passes on this thread before sending the + //thread header content. RamCore ramCore( coreTgt, thread ); - if(doRamming == true) + if(doRamming) { + //Do the ramming setup SBE_EXEC_HWP_NOARG(fapiRc, ramCore.ram_setup) if( fapiRc != FAPI2_RC_SUCCESS ) { - SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%2X" - "coreChipletId:0x%02X Proc:0x%02X", - thread, chipUnitNum, procChipId); - // Skip this thread since ram setup failed, try - // to get data for the Next Thread, but what - // about this fapiRc - continue; + SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%2X" + "coreChipletId:0x%02X Proc:0x%02X",thread, chipUnitNum, + procChipId); + + //Mark the coreState to be bad for this thread in the + //thread header to indicae the non-existence of register + //data. + dumpThreadHdr.coreState = INVALID_CORE_STATE; + doRamming = false; } } - // If setup passes, then go for get_reg() - Enum_RegType type = REG_SPR; - // Construct PIR for the thread - pir.procGrpId = procGrpId; - pir.procChipId = procChipId; - pir.chipUnitNum = chipUnitNum; - pir.thread = thread; + //Send the thread header content + fapiRc = PBAInterface.accessWithBuffer(&dumpThreadHdr, + sizeof(dumpThreadHdr),false); + if(fapiRc != fapi2::FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "Failed to write thread header to hostboot"); + break; + } + + if(!doRamming) + { + //Do not attempt to read the register data related to + //current core / Thread as the core status is not valid + continue; + } + + uint32_t totalRegisters=(sizeof(SPR_GPR_list)/sizeof(uint16_t)); // Loop over the combined list of registers - for( uint32_t regIdx=0; regIdx<(sizeof(SPR_GPR_list)/sizeof(uint16_t)); regIdx++ ) + for( uint32_t regIdx=0; regIdx < totalRegisters; regIdx++ ) { + // Start filling up the rest of data structure + Enum_RegType type = REG_SPR; + dumpRegData.regType = SPR_REG_TYPE; // Switch to GPRs once SPRs are over in the list if(regIdx >= SPR_LIST_SIZE) { type = REG_GPR; + dumpRegData.regType = GPR_REG_TYPE; + } + dumpRegData.regNum = SPR_GPR_list[regIdx]; + if((regIdx+1) == totalRegisters) + { + dumpRegData.isLastReg = true; + } + else + { + dumpRegData.isLastReg = false; } - // Start filling up the rest of data structure - dump.pir = pir; - dump.coreState = coreState; - dump.regNum = SPR_GPR_list[regIdx]; - dump.regVal = 0; - if(doRamming == true) + fapi2::buffer data64; + SBE_EXEC_HWP(fapiRc, ramCore.get_reg, type, + SPR_GPR_list[regIdx], &data64, true) + + if( fapiRc != FAPI2_RC_SUCCESS ) { - fapi2::buffer data64; - SBE_EXEC_HWP(fapiRc, ramCore.get_reg, type, - SPR_GPR_list[regIdx], &data64, true) - if( fapiRc != FAPI2_RC_SUCCESS ) - { - SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x " + SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x " "coreChipletId:0x%02x, regNr:%u regType:%u", - thread, chipUnitNum, SPR_GPR_list[regIdx], type); - // If get_reg fails,we need to indicate hostboot - // that data fetch failed, use this signature - dump.regVal = 0xDEADBEEFDEADBEEFULL; - } - else - { - dump.regVal = data64; - } + thread, chipUnitNum, SPR_GPR_list[regIdx], type); + dumpRegData.isRegDataValid = false;//Invalid data + dumpRegData.regVal = (uint64_t)fapiRc; //Save FAPI_RC + dumpRegData.isFfdcPresent = true; //Indicate FFDC pressence + dumpRegData.isLastReg = true;//No more registers fetched + } + else + { + dumpRegData.regVal = data64; + dumpRegData.isRegDataValid = true; //Valid Data + dumpRegData.isFfdcPresent = false; //No FFDC } - // PBA it to the stash address + //Send the Register data to the Hostboot using PBA fapiRc = PBAInterface.accessWithBuffer( - &dump, - sizeof(dump), - false); + &dumpRegData, sizeof(dumpRegData),false); if(fapiRc != fapi2::FAPI2_RC_SUCCESS) { - SBE_ERROR(SBE_FUNC "failed in writing to hostboot"); + SBE_ERROR(SBE_FUNC "failed in register content to hostboot"); break; } - } + + //Add the FAPI FFDC if fetching the register content had + //failed + if(dumpRegData.isFfdcPresent) + { + /* 128 Bytes FAPI FFDC which will be added to the data + * shared with the hostboot when accessing the + * SPR/GPR data fails.*/ + uint32_t FFDCData[128] = {0xFF}; + + //Send the Register data to the Hostboot using PBA + fapiRc = PBAInterface.accessWithBuffer( + &FFDCData, sizeof(FFDCData),false); + if(fapiRc != fapi2::FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "failed to write failure FFDC to hostboot"); + break; + } + + //Stop reading reset of the register data and exit out + //of register loop and continue for next thread. + break; + } + + }//End of Register loop + if(fapiRc) { break; } - // HWP team does not care about cleanup for failure case.i - // So call cleaup only for success case. - // Clean up the ram core setup - if(doRamming == true) + + //Clean up the ram core setup + SBE_EXEC_HWP_NOARG(fapiRc, ramCore.ram_cleanup) + if( fapiRc != FAPI2_RC_SUCCESS ) { - SBE_EXEC_HWP_NOARG(fapiRc, ramCore.ram_cleanup) - if( fapiRc != FAPI2_RC_SUCCESS ) - { - SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%02X" + SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%02X" " coreChipletId:0x%02X", thread, chipUnitNum); - // Don't break, continue for the next thread - } + // Don't break, continue for the next thread + continue; } - } + + } //End of Thread Loop if(fapiRc) { break; } - } + }//End of Core loop + // Just see that we are pushing the last PBA Frame here so as to flush // anything which is stuck before of a non-aligned frame. - sbeArchRegDumpFormat_t dump_dummy = {}; + sbeArchRegDumpThreadHdr_t dump_dummy = {}; fapiRc = PBAInterface.accessWithBuffer(&dump_dummy, sizeof(dump_dummy), true); if(fapiRc != fapi2::FAPI2_RC_SUCCESS) { SBE_ERROR(SBE_FUNC "failed to write the last frame to hostboot"); break; } - }while(0); + }while(0); SBE_EXIT(SBE_FUNC); + return fapiRc; #undef SBE_FUNC } diff --git a/src/sbefw/core/sbeHostMsg.H b/src/sbefw/core/sbeHostMsg.H index 4978417b..17201838 100644 --- a/src/sbefw/core/sbeHostMsg.H +++ b/src/sbefw/core/sbeHostMsg.H @@ -186,6 +186,22 @@ typedef struct void init(); } sbeSbe2PsuRespHdr_t; +/* @brief Format to dump out the architected register on the host memory + * Host may use this format to fetch all the register data/state + */ + +#define DUMP_STRUCT_VERSION_ID 0x1 + +/* Processor architected dump header. This header is per processor*/ +typedef struct { + uint8_t ownerId; /* FSP or SBE */ + uint8_t version; /* Interface version number*/ + uint16_t core_cnt; /* Cores per chip */ + uint16_t thread_count; /* Max Threads per proc chip */ + uint16_t reg_cnt; /* Max number of registers per thread */ +} sbeArchRegDumpProcHdr_t; //8Bytes + + /* @brief Format of PIR */ typedef struct { @@ -193,18 +209,53 @@ typedef struct uint32_t procChipId:3; uint32_t chipUnitNum:6; uint32_t thread:2; -} sbe_pir_t; +} sbe_pir_t; //4Bytes -/* @brief Format to dump out the architected register on the host memory - * Host may use this format to fetch all the register data/state +/*Thread Specific header*/ +typedef struct +{ + sbe_pir_t pir; // PIR value of thread corrsponding to the register + uint32_t coreState:8; // State of core in which this thread is present + // Expect register data only if core status is '0' + uint32_t reserved:24; +} sbeArchRegDumpThreadHdr_t; //8Bytes + + +/** + * @brief Defines the structure for storing the SPR/GPR register data + * + * @var isRegDataValid :'1'- Variable regVal will contain valid register data + * '0'- Variable regVal will contain fapiRC value + * + * @var isLastReg :'1' - Data is collected for the last SPR/GPR register + * '0' - otherwise. + * + * @var isFfdcPresent :'1' - Failing FAPI FFDC is shared + * '0' - Failing FFDC is not present + * + * @var reserved0 :Reserved for future use and padding + * + * @var regType :Indicates type of register(SPR/GPR) + * + * @var reserved1 :Reserved for future use and padding + * + * @var regNum :Address of the SPR/GPR register + * + * @var regVal :if isRegDataValid is '0' - Valid Register value + * isRegDataValid is '!=0'- fapiRC value. */ typedef struct { - sbe_pir_t pir; // PIR value of thread corrsponding to the register - uint32_t coreState:8; // State of core in which this thread is present - uint32_t reserved:8; // Reserved - uint32_t regNum:16; // Register Number - uint64_t regVal; // Register Value -} sbeArchRegDumpFormat_t; + uint64_t isRegDataValid:1; + uint64_t isLastReg:1; + uint64_t isFfdcPresent:1; + uint64_t reseverd0:5; + uint64_t regType:8; + uint64_t reserved1:16; + uint64_t regNum:32; + uint64_t regVal; +} sbeArchRegDumpEntries_t; + + #endif // __SBEFW_SBEHOST_MSG_H -- cgit v1.2.1