diff options
author | Sachin Gupta <sgupta2m@in.ibm.com> | 2016-03-21 07:35:17 -0500 |
---|---|---|
committer | AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com> | 2016-05-17 05:16:07 -0400 |
commit | 55f9061a6810f7122765bcafad382ed98f67dd5f (patch) | |
tree | dbd80ee2a727188f908186176765d6fe312d4c31 /sbe/sbefw | |
parent | 1349a59f0b860c268bd178ad099269dccd9f8a10 (diff) | |
download | talos-sbe-55f9061a6810f7122765bcafad382ed98f67dd5f.tar.gz talos-sbe-55f9061a6810f7122765bcafad382ed98f67dd5f.zip |
Reg access support
RTC: 128984
Change-Id: I6c5637de94077cca58a72d20a88c6db20c137632
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22279
Tested-by: Jenkins Server
Reviewed-by: RAJA DAS <rajadas2@in.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'sbe/sbefw')
-rw-r--r-- | sbe/sbefw/sbeFifoMsgUtils.C | 40 | ||||
-rw-r--r-- | sbe/sbefw/sbeFifoMsgUtils.H | 11 | ||||
-rw-r--r-- | sbe/sbefw/sbeSpMsg.H | 47 | ||||
-rw-r--r-- | sbe/sbefw/sbe_sp_intf.H | 15 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdgeneric.C | 3 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdparser.C | 23 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdregaccess.C | 248 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdregaccess.H | 33 | ||||
-rw-r--r-- | sbe/sbefw/sbefwfiles.mk | 2 |
9 files changed, 421 insertions, 1 deletions
diff --git a/sbe/sbefw/sbeFifoMsgUtils.C b/sbe/sbefw/sbeFifoMsgUtils.C index f926bfdd..a86f1363 100644 --- a/sbe/sbefw/sbeFifoMsgUtils.C +++ b/sbe/sbefw/sbeFifoMsgUtils.C @@ -294,3 +294,43 @@ uint32_t sbeDownFifoSignalEot (void) #undef SBE_FUNC } + +uint32_t sbeDsSendRespHdr(const sbeRespGenHdr_t &i_hdr, + const sbeResponseFfdc_t &i_ffdc ) +{ + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + do + { + uint32_t distance = 1; //initialise by 1 for entry count itself. + uint32_t len = sizeof( i_hdr )/sizeof(uint32_t); + // sbeDownFifoEnq_mult. + rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &i_hdr); + if (rc) + { + break; + } + distance += len; + + // If no ffdc , exit; + if( i_ffdc.getRc() ) + { + len = sizeof(i_ffdc)/sizeof(uint32_t); + rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &i_ffdc); + if (rc) + { + break; + } + distance += len; + } + len = sizeof(distance)/sizeof(uint32_t); + //@TODO via RTC 129076. + //Need to add FFDC data as well. + rc = sbeDownFifoEnq_mult ( len, &distance); + if (rc) + { + break; + } + + }while(0); + return rc; +} diff --git a/sbe/sbefw/sbeFifoMsgUtils.H b/sbe/sbefw/sbeFifoMsgUtils.H index 83d033c4..d9d460f3 100644 --- a/sbe/sbefw/sbeFifoMsgUtils.H +++ b/sbe/sbefw/sbeFifoMsgUtils.H @@ -155,4 +155,15 @@ void sbeBuildMinRespHdr ( uint32_t *io_pBuf, */ uint32_t sbeDownFifoSignalEot (void); +/** + * @brief sbeDsSendRespHdr : Send response header to DS FIFO + * - This also sends the FFDC if exist. + * + * @param[in] i_hdr Response Header + * @param[in] i_ffdc FFDC object + * + * @return Rc from the underlying scom utility + */ +uint32_t sbeDsSendRespHdr(const sbeRespGenHdr_t &i_hdr, + const sbeResponseFfdc_t &i_ffdc ); #endif // __SBEFW_SBEFIFOMSGUTILS_H diff --git a/sbe/sbefw/sbeSpMsg.H b/sbe/sbefw/sbeSpMsg.H index 7d8e3fb1..df2730cb 100644 --- a/sbe/sbefw/sbeSpMsg.H +++ b/sbe/sbefw/sbeSpMsg.H @@ -144,7 +144,7 @@ typedef struct sbeResponseFfdc * * @return fapiRc */ - uint32_t getRc() + uint32_t getRc() const { return lowFapiRc; } @@ -475,5 +475,50 @@ typedef struct } } }sbeCntlInstRegMsgHdr_t; +/** + * @brief Reg access message header + */ +typedef struct +{ + uint32_t reserved:8; + uint32_t coreChiplet:8; + uint32_t threadNr:4; + uint32_t regType:4; + uint32_t numRegs:8; + + /** + * @brief checks if it is valid request. + * + * @return true if valid request, false otherwise + */ + bool isValidRequest() const + { + return (( SBE_REG_ACCESS_FPR >= regType ) + &&( SBE_MAX_REG_ACCESS_REGS >= numRegs ) + &&( SMT4_THREAD3 >= threadNr ) + &&( SMT4_CORE0_ID <= coreChiplet ) + &&( SMT4_CORE_ID_MAX >= coreChiplet )) ? true:false; + } +}sbeRegAccessMsgHdr_t; + +/** + * @brief reg scom package + */ +typedef struct +{ + uint32_t regNr; + uint32_t hiData; + uint32_t lowData; + + /** + * @brief data for a register. + * + * @return data. + */ + uint64_t getData() const + { + return (((uint64_t)hiData << 32 ) | lowData ); + } +}sbeRegAccessPackage_t; #endif // __SBEFW_SBESP_MSG_H diff --git a/sbe/sbefw/sbe_sp_intf.H b/sbe/sbefw/sbe_sp_intf.H index 7f5fac19..62894b6a 100644 --- a/sbe/sbefw/sbe_sp_intf.H +++ b/sbe/sbefw/sbe_sp_intf.H @@ -286,6 +286,10 @@ enum sbeSramAccessMode DEBUG_MODE = 0x2, CIRCULAR_MODE = 0x3, }; +/* + * Constants for maximum number of register supported in reg access chipop. + */ +static const uint32_t SBE_MAX_REG_ACCESS_REGS = 64; /** * @brief Error Mode enum @@ -330,6 +334,17 @@ enum sbeThreadOps THREAD_SRESET_INS = 0x3, }; +/** + * @brief enums for Reg access register type + * + */ +enum sbeRegAccesRegType +{ + SBE_REG_ACCESS_GPR = 0x00, + SBE_REG_ACCESS_SPR = 0x01, + SBE_REG_ACCESS_FPR = 0x02, +}; + #ifdef __cplusplus } #endif diff --git a/sbe/sbefw/sbecmdgeneric.C b/sbe/sbefw/sbecmdgeneric.C index 8fe7b6a2..a1d62aa5 100644 --- a/sbe/sbefw/sbecmdgeneric.C +++ b/sbe/sbefw/sbecmdgeneric.C @@ -44,6 +44,9 @@ sbeCapabilityRespMsg::sbeCapabilityRespMsg() capability[INSTRUCTION_CTRL_CAPABILITY_START_IDX] = CONTROL_INSTRUCTIONS_SUPPPORTED; + capability[REGISTER_CAPABILITY_START_IDX] = + GET_REGISTER_SUPPPORTED | + PUT_REGISTER_SUPPPORTED ; } // Functions //---------------------------------------------------------------------------- diff --git a/sbe/sbefw/sbecmdparser.C b/sbe/sbefw/sbecmdparser.C index 6769be77..9dc6c094 100644 --- a/sbe/sbefw/sbecmdparser.C +++ b/sbe/sbefw/sbecmdparser.C @@ -10,6 +10,7 @@ #include "sbecmdiplcontrol.H" #include "sbecmdgeneric.H" #include "sbecmdmemaccess.H" +#include "sbecmdregaccess.H" #include "sbecmdcntrldmt.H" #include "sbecmdsram.H" #include "sbecmdcntlinst.H" @@ -114,6 +115,22 @@ static sbeCmdStruct_t g_sbeInstructionCntlCmdArray[] = SBE_FENCE_AT_CONTINUOUS_IPL, }, }; +////////////////////////////////////////////////////////////// +// @brief g_sbeRegAccessCmdArray +// +////////////////////////////////////////////////////////////// +static sbeCmdStruct_t g_sbeRegAccessCmdArray [] = +{ + {sbeGetReg, + SBE_CMD_GETREG, + SBE_FENCE_AT_CONTINUOUS_IPL, + }, + + {sbePutReg, + SBE_CMD_PUTREG, + SBE_FENCE_AT_CONTINUOUS_IPL, + }, +}; ////////////////////////////////////////////////////////////// // @brief g_sbeCoreStateControlCmdArray @@ -170,6 +187,12 @@ uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass, *o_ppCmd = (sbeCmdStruct_t*)g_sbeInstructionCntlCmdArray; break; + case SBE_CMD_CLASS_REGISTER_ACCESS: + l_numCmds = sizeof(g_sbeRegAccessCmdArray) / + sizeof(sbeCmdStruct_t); + *o_ppCmd = (sbeCmdStruct_t*)g_sbeRegAccessCmdArray; + break; + // PSU Commands case SBE_PSU_CMD_CLASS_CORE_STATE: l_numCmds = sizeof(g_sbeCoreStateControlCmdArray) / diff --git a/sbe/sbefw/sbecmdregaccess.C b/sbe/sbefw/sbecmdregaccess.C new file mode 100644 index 00000000..1b0fbe39 --- /dev/null +++ b/sbe/sbefw/sbecmdregaccess.C @@ -0,0 +1,248 @@ +/* + * @file: ppe/sbe/sbefw/sbecmdregaccess.C + * + * @brief This file contains the SBE Reg Access chipOps + * + */ + +#include "sbecmdregaccess.H" +#include "sbefifo.H" +#include "sbe_sp_intf.H" +#include "sbetrace.H" +#include "sbeFifoMsgUtils.H" +#include "p9_ram_core.H" + +using namespace fapi2; + +Enum_RegType getRegType( const sbeRegAccessMsgHdr_t ®Req) +{ + Enum_RegType type = REG_GPR; + switch( regReq.regType ) + { + case SBE_REG_ACCESS_SPR: + type = REG_SPR; + break; + + case SBE_REG_ACCESS_FPR: + type = REG_FPR; + break; + } + return type; +} + +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +uint32_t sbeGetReg(uint8_t *i_pArg) +{ + #define SBE_FUNC " sbeGetReg " + SBE_ENTER(SBE_FUNC); + + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + sbeRegAccessMsgHdr_t regReqMsg; + uint32_t reqData[SBE_MAX_REG_ACCESS_REGS]; + sbeRespGenHdr_t respHdr; + respHdr.init(); + sbeResponseFfdc_t ffdc; + ReturnCode fapiRc; + + do + { + // Get the reg access header + uint32_t len = sizeof(sbeRegAccessMsgHdr_t)/sizeof(uint32_t); + rc = sbeUpFifoDeq_mult (len, (uint32_t *)®ReqMsg, false); + + // If FIFO access failure + if (rc != SBE_SEC_OPERATION_SUCCESSFUL) + { + // Let command processor routine to handle the RC. + break; + } + if( false == regReqMsg.isValidRequest() ) + { + SBE_ERROR(SBE_FUNC" Invalid request. core: 0x%02x threadNr:0x%x" + " regType:0x%01x numRegs:0x%02x", regReqMsg.coreChiplet, + regReqMsg.threadNr, regReqMsg.regType, regReqMsg.numRegs); + + respHdr.setStatus( SBE_PRI_INVALID_DATA, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + break; + } + + len = regReqMsg.numRegs; + rc = sbeUpFifoDeq_mult (len, reqData, true); + if (rc != SBE_SEC_OPERATION_SUCCESSFUL) + { + break; + } + uint8_t core = regReqMsg.coreChiplet; + RamCore ramCore( plat_getTargetHandleByChipletNumber(core), + regReqMsg.threadNr ); + + fapiRc = ramCore.ram_setup(); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%x" + "chipletId:0x%02x", regReqMsg.threadNr, core); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + break; + } + + fapi2::buffer<uint64_t> data64; + uint64_t respData = 0; + for( uint32_t regIdx = 0; regIdx < regReqMsg.numRegs; regIdx++ ) + { + fapiRc = ramCore.get_reg( getRegType(regReqMsg), reqData[regIdx], + &data64, true ); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x" + "chipletId:0x%02x, regNr:%u regType:%u ", + regReqMsg.threadNr, core, reqData[regIdx], + regReqMsg.regType); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + break; + } + SBE_DEBUG(SBE_FUNC" getting response data"); + respData = data64; + // Now enqueue into the downstream FIFO + len = sizeof( respData )/sizeof(uint32_t); + rc = sbeDownFifoEnq_mult (len, ( uint32_t *)&respData); + if (rc) + { + break; + } + } + // HWP team does not care about cleanup for failure case. + // So call cleaup only for success case. + if( ffdc.getRc() ) + { + break; + } + fapiRc = ramCore.ram_cleanup(); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%x" + "chipletId:0x%02x", regReqMsg.threadNr, core); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + } + }while(false); + + if ( SBE_SEC_OPERATION_SUCCESSFUL == rc ) + { + rc = sbeDsSendRespHdr( respHdr, ffdc); + } + + return rc; + #undef SBE_FUNC +} +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +uint32_t sbePutReg(uint8_t *i_pArg) +{ + #define SBE_FUNC " sbePutReg " + SBE_ENTER(SBE_FUNC); + + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + sbeRegAccessMsgHdr_t regReqMsg; + sbeRespGenHdr_t respHdr; + respHdr.init(); + sbeResponseFfdc_t ffdc; + ReturnCode fapiRc; + + do + { + // Get the reg access header + uint32_t len = sizeof(sbeRegAccessMsgHdr_t)/sizeof(uint32_t); + rc = sbeUpFifoDeq_mult (len, (uint32_t *)®ReqMsg, false); + + // If FIFO access failure + if (rc != SBE_SEC_OPERATION_SUCCESSFUL) + { + // Let command processor routine to handle the RC. + break; + } + if( false == regReqMsg.isValidRequest() ) + { + SBE_ERROR(SBE_FUNC" Invalid request. threadNr:0x%x" + " regType:0x%02x numRegs:0x%02x", regReqMsg.threadNr, + regReqMsg.regType, regReqMsg.numRegs); + respHdr.setStatus( SBE_PRI_INVALID_DATA, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + break; + } + + sbeRegAccessPackage_t regPkg[SBE_MAX_REG_ACCESS_REGS]; + len = (sizeof(sbeRegAccessPackage_t)/sizeof(uint32_t)) * + regReqMsg.numRegs; + rc = sbeUpFifoDeq_mult (len, (uint32_t *) regPkg,true ); + if (rc != SBE_SEC_OPERATION_SUCCESSFUL) + { + break; + } + uint8_t core = regReqMsg.coreChiplet; + RamCore ramCore( plat_getTargetHandleByChipletNumber(core), + regReqMsg.threadNr ); + + fapiRc = ramCore.ram_setup(); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%x" + "chipletId:0x%02x", regReqMsg.threadNr, core); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + break; + } + + fapi2::buffer<uint64_t> data64; + for( uint32_t regIdx = 0; regIdx < regReqMsg.numRegs; regIdx++ ) + { + data64 = regPkg[regIdx].getData(); + fapiRc = ramCore.put_reg( getRegType(regReqMsg), + regPkg[regIdx].regNr, + &data64, true ); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x" + "chipletId:0x%02x, regNr:%u regType:%u ", + regReqMsg.threadNr, core, regPkg[regIdx].regNr, + regReqMsg.regType); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + break; + } + } + // HWP team does not care about cleanup for failure case. + // So call cleaup only for success case. + if( ffdc.getRc() ) + { + break; + } + fapiRc = ramCore.ram_cleanup(); + if( fapiRc ) + { + SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%x" + " chipletId:0x%02x", regReqMsg.threadNr, core); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + } + + }while(false); + + if ( SBE_SEC_OPERATION_SUCCESSFUL == rc ) + { + rc = sbeDsSendRespHdr( respHdr, ffdc); + } + + return rc; + #undef SBE_FUNC +} + diff --git a/sbe/sbefw/sbecmdregaccess.H b/sbe/sbefw/sbecmdregaccess.H new file mode 100644 index 00000000..b297fc59 --- /dev/null +++ b/sbe/sbefw/sbecmdregaccess.H @@ -0,0 +1,33 @@ +/* + * @file: ppe/sbe/sbefw/sbecmdregaccess.H + * + * @brief This file contains the Interfaces for the SCOM Access chip-ops + * + */ + +#ifndef __SBEFW_SBECMDREGACCESS_H +#define __SBEFW_SBECMDREGACCESS_H + +#include <stdint.h> + +/** + * @brief sbeGetRegs : Get the reg data + * + * @param[in] i_pArg Buffer to be passed to the function (not used as of now) + * + * @return Rc from the FIFO access utility + */ +uint32_t sbeGetReg(uint8_t *i_pArg); + + +/** + * @brief sbePutRegs : Put the reg data + * + * @param[in] i_pArg Buffer to be passed to the function (not used as of now) + * + * @return Rc from the FIFO access utility + */ +uint32_t sbePutReg(uint8_t *i_pArg); + + +#endif /* __SBEFW_SBECMDREGACCESS_H */ diff --git a/sbe/sbefw/sbefwfiles.mk b/sbe/sbefw/sbefwfiles.mk index f666bdb6..d38df07d 100644 --- a/sbe/sbefw/sbefwfiles.mk +++ b/sbe/sbefw/sbefwfiles.mk @@ -14,6 +14,8 @@ SBEFW-CPP-SOURCES += sbecmdcntrldmt.C SBEFW-CPP-SOURCES += sbecmdsram.C SBEFW-CPP-SOURCES += sberegaccess.C SBEFW-CPP-SOURCES += sbecmdcntlinst.C +SBEFW-CPP-SOURCES += sbecmdregaccess.C + SBEFW-C-SOURCES = SBEFW-S-SOURCES = |