summaryrefslogtreecommitdiffstats
path: root/sbe/sbefw
diff options
context:
space:
mode:
authorSachin Gupta <sgupta2m@in.ibm.com>2016-03-21 07:35:17 -0500
committerAMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>2016-05-17 05:16:07 -0400
commit55f9061a6810f7122765bcafad382ed98f67dd5f (patch)
treedbd80ee2a727188f908186176765d6fe312d4c31 /sbe/sbefw
parent1349a59f0b860c268bd178ad099269dccd9f8a10 (diff)
downloadtalos-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.C40
-rw-r--r--sbe/sbefw/sbeFifoMsgUtils.H11
-rw-r--r--sbe/sbefw/sbeSpMsg.H47
-rw-r--r--sbe/sbefw/sbe_sp_intf.H15
-rw-r--r--sbe/sbefw/sbecmdgeneric.C3
-rw-r--r--sbe/sbefw/sbecmdparser.C23
-rw-r--r--sbe/sbefw/sbecmdregaccess.C248
-rw-r--r--sbe/sbefw/sbecmdregaccess.H33
-rw-r--r--sbe/sbefw/sbefwfiles.mk2
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 &regReq)
+{
+ 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 *)&regReqMsg, 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 *)&regReqMsg, 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 =
OpenPOWER on IntegriCloud