summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorspashabk-in <shakeebbk@in.ibm.com>2018-03-06 03:15:50 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2018-03-27 01:00:05 -0400
commit90d4e44287359528431e6a87c95dd4581e493264 (patch)
treeb36d8c954c01d023cd1713aede8048fd31661fba /src
parent8a161b11a53911c001bfe96d46135420338a65c6 (diff)
downloadtalos-sbe-90d4e44287359528431e6a87c95dd4581e493264.tar.gz
talos-sbe-90d4e44287359528431e6a87c95dd4581e493264.zip
PSU get capabilities chip-op
Support PSU get capabilities chipop Change-Id: I36980433aaa70323c5b2b80a89d8618d03ea8a60 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/55091 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: RAJA DAS <rajadas2@in.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/sbefw/app/common/sbecmdgeneric.C68
-rw-r--r--src/sbefw/app/common/sbecmdgeneric.H28
-rw-r--r--src/sbefw/app/power/chipop_table.C7
-rw-r--r--src/sbefw/app/power/sbecmdgeneric.C31
-rw-r--r--src/sbefw/core/sbe_host_intf.H70
-rwxr-xr-xsrc/test/testcases/test.xml4
-rw-r--r--src/test/testcases/testPSUGetCapabilities.py154
7 files changed, 358 insertions, 4 deletions
diff --git a/src/sbefw/app/common/sbecmdgeneric.C b/src/sbefw/app/common/sbecmdgeneric.C
index 813df873..cdcd7575 100644
--- a/src/sbefw/app/common/sbecmdgeneric.C
+++ b/src/sbefw/app/common/sbecmdgeneric.C
@@ -42,6 +42,7 @@
#include "sbeHostUtils.H"
#include "sbeglobals.H"
#include "sbeXipUtils.H"
+#include "sbeMemAccessInterface.H"
#include "fapi2.H"
//#include "p9_xip_image.h"
@@ -54,6 +55,10 @@ static const uint32_t SBE_CAPABILITES_LEN_FIFO =
sizeof(sbeCapabilityRespMsg_t) -
(sizeof(uint32_t) *
(SBE_MAX_CAPABILITIES - CAPABILITIES_LAST_INDEX_FIFO - 1));
+static const uint32_t SBE_CAPABILITES_LEN_PSU =
+ sizeof(sbeCapabilityRespMsg_t) -
+ (sizeof(uint32_t) *
+ (SBE_MAX_CAPABILITIES - CAPABILITIES_LAST_INDEX_PSU - 1));
sbeCapabilityRespMsg::sbeCapabilityRespMsg() : capability{}
{
@@ -69,6 +74,68 @@ sbeCapabilityRespMsg::sbeCapabilityRespMsg() : capability{}
}
// Functions
//----------------------------------------------------------------------------
+uint32_t sbePsuGetCapabilities(uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbePsuGetCapabilities "
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+
+ sbePsuGetCapabilitiesReq_t req = {};
+
+ sbeCapabilityRespMsg_t capMsg;
+ updatePsuCapabilities(capMsg.capability);
+
+ do
+ {
+ rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ sizeof(req)/sizeof(uint64_t),
+ (uint64_t*)&req,
+ true);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc);
+
+ SBE_DEBUG(SBE_FUNC "at addr[0x%08X%08X] len[0x%08X%08X]",
+ SBE::higher32BWord(req.address),
+ SBE::lower32BWord(req.address),
+ SBE::higher32BWord(req.size),
+ SBE::lower32BWord(req.size));
+
+ if((req.size < SBE_CAPABILITES_LEN_PSU) ||
+ (req.size % sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES))
+ {
+ SBE_ERROR(SBE_FUNC " incorrect memory allocation");
+ SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_DATA,
+ SBE_SEC_INVALID_PARAMS);
+ break;
+ }
+ p9_PBA_oper_flag l_myPbaFlag;
+ l_myPbaFlag.setOperationType(p9_PBA_oper_flag::INJ);
+
+ sbeMemAccessInterface l_PBAInterface(
+ SBE_MEM_ACCESS_PBA,
+ req.address,
+ &l_myPbaFlag,
+ SBE_MEM_ACCESS_WRITE,
+ sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES);
+ l_fapiRc = l_PBAInterface.accessWithBuffer(
+ &capMsg,
+ SBE_CAPABILITES_LEN_PSU,
+ true);
+ if(l_fapiRc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "failed in writing to host memory");
+ SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(
+ SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+ } while(false);
+
+ // Send the response
+ sbePSUSendResponse(SBE_GLOBAL->sbeSbe2PsuRespHdr, l_fapiRc, rc);
+ return rc;
+ #undef SBE_FUNC
+}
+
uint32_t sbeGetCapabilities (uint8_t *i_pArg)
{
#define SBE_FUNC "sbeGetCapabilities "
@@ -490,4 +557,3 @@ uint32_t sbeReadMem( uint8_t *i_pArg )
#undef SBE_FUNC
}
#endif //not __SBEFW_SEEPROM__
-
diff --git a/src/sbefw/app/common/sbecmdgeneric.H b/src/sbefw/app/common/sbecmdgeneric.H
index 471304c9..633a6bad 100644
--- a/src/sbefw/app/common/sbecmdgeneric.H
+++ b/src/sbefw/app/common/sbecmdgeneric.H
@@ -91,16 +91,32 @@ typedef struct stashMsg
uint64_t addr;
}stashMsg_t;
+// SBE PSU get capabilities request
+typedef struct
+{
+ uint64_t size;
+ uint64_t address;
+} sbePsuGetCapabilitiesReq_t;
+
/**
* @brief Update Fifo capabilities
*
- * @param[in] capability Pointer to capcbility array
+ * @param[in] capability Pointer to capability array
*
* @return void
*/
void updateFifoCapabilities(uint32_t * capability);
/**
+ * @brief Update PSU capabilities
+ *
+ * @param[in] capability Pointer to capability array
+ *
+ * @return void
+ */
+void updatePsuCapabilities(uint32_t * capability);
+
+/**
* @brief retrieve SBE FFDC on request from FSP. (0xA801)
*
* @param[in] i_pArg Buffer to be passed to the function (not used as of now)
@@ -162,6 +178,7 @@ uint32_t sbeSetSystemFabricMap(uint8_t *i_pArg);
* @return Rc from the Psu access utility
*/
uint32_t sbeStashKeyAddrPair(uint8_t *i_pArg);
+
/**
* @brief Read the data from SBE memory (0xD703)
*
@@ -170,3 +187,12 @@ uint32_t sbeStashKeyAddrPair(uint8_t *i_pArg);
* @return Rc from the Psu access utility
*/
uint32_t sbeReadMem(uint8_t *i_pArg);
+
+/**
+ * @brief SBE Psu get capabilities(0xD702)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the Psu access utility
+ */
+uint32_t sbePsuGetCapabilities(uint8_t *i_pArg);
diff --git a/src/sbefw/app/power/chipop_table.C b/src/sbefw/app/power/chipop_table.C
index e74c6c9a..4ba84581 100644
--- a/src/sbefw/app/power/chipop_table.C
+++ b/src/sbefw/app/power/chipop_table.C
@@ -291,7 +291,12 @@ CMD_ARR(
//////////////////////////////////////////////////////////////
CMD_ARR(
D7,
- {sbeReadMem,
+ {sbePsuGetCapabilities,
+ SBE_PSU_GENERIC_MSG_GET_CAPABILITIES,
+ SBE_NO_FENCE,
+ },
+
+ {sbeReadMem,
SBE_PSU_GENERIC_MSG_READ_SBE_MEM,
SBE_NO_FENCE,
},
diff --git a/src/sbefw/app/power/sbecmdgeneric.C b/src/sbefw/app/power/sbecmdgeneric.C
index 6f6afa91..8e0762ac 100644
--- a/src/sbefw/app/power/sbecmdgeneric.C
+++ b/src/sbefw/app/power/sbecmdgeneric.C
@@ -50,6 +50,36 @@ using namespace fapi2;
#ifdef __SBEFW_SEEPROM__
+void updatePsuCapabilities(uint32_t * capability)
+{
+ capability[PSU_GENERIC_CAPABILTITY_START_IDX] =
+ PSU_HWP_FFDC_COLLECTION_SUPPORTED |
+ PSU_SBE_FFDC_COLLECTION_SUPPORTED |
+ PSU_ADDRESS_BLACKLIST_SUPPORTED |
+ PSU_HOST_COMMAND_INTERFACE_SUPPORTED;
+
+ capability[PSU_CORE_CONTROL_CAPABILITY_START_IDX] =
+ PSU_CONTROL_DEADMAN_LOOP;
+
+ capability[PSU_RING_CAPABILITY_START_IDX] =
+ PSU_PUT_RING_FROM_IMAGE_SUPPORTED;
+
+ capability[PSU_TIMER_CAPABILITY_START_IDX] =
+ PSU_CONTROL_TIMER_SUPPORTED;
+
+ capability[PSU_SECURITY_CONTROL_CAPABILITY_START_IDX] =
+ PSU_UNSECURE_MEM_REGION_SUPPORTED;
+
+ capability[PSU_GENERIC_CHIPOP_CAPABILITY_START_IDX] =
+ PSU_GET_SBE_FFDC_SUPPPORTED |
+ PSU_GET_SBE_CAPABILITIES_SUPPPORTED |
+ PSU_READ_SBE_SEEPROM_SUPPORTED |
+ PSU_SET_FFDC_ADDRESS_SUPPORTED |
+ PSU_QUISCE_SUPPORTED |
+ PSU_SET_SYSTEM_FABRIC_ID_MAP_SUPPORTED |
+ PSU_STASH_MPIPL_CONFIG_SUPPORTED;
+
+}
void updateFifoCapabilities(uint32_t * capability)
{
// @TODO via RTC : 160602
@@ -90,4 +120,3 @@ void updateFifoCapabilities(uint32_t * capability)
#ifndef __SBEFW_SEEPROM__
#endif //not __SBEFW_SEEPROM__
-
diff --git a/src/sbefw/core/sbe_host_intf.H b/src/sbefw/core/sbe_host_intf.H
index 6bb11cd8..975a94fa 100644
--- a/src/sbefw/core/sbe_host_intf.H
+++ b/src/sbefw/core/sbe_host_intf.H
@@ -96,6 +96,7 @@ enum sbePsuUpdateMemoryRegionMessages
*/
enum sbePsuGenericMessages
{
+ SBE_PSU_GENERIC_MSG_GET_CAPABILITIES = 0x02,
SBE_PSU_GENERIC_MSG_READ_SBE_MEM = 0x03,
SBE_PSU_GENERIC_MSG_SET_FFDC_ADDR = 0x04,
SBE_PSU_GENERIC_MSG_QUIESCE = 0x05,
@@ -133,4 +134,73 @@ enum sbeUnsecureMemRegionControlFlags
SBE_MEM_REGION_CLOSE = 0x0020,
};
+/**
+ * @brief capabilities index values.
+ * Get Capability response will return 18 capabilities. This
+ * enum tells the index for each capability. Currently each generic
+ * functionality( scom, IPL ) etc span across two capabilities.
+ */
+enum PSU_CAPABILITIES_INDEX
+{
+ PSU_GENERIC_CAPABILTITY_START_IDX = 0,
+ PSU_CORE_CONTROL_CAPABILITY_START_IDX = 2,
+ PSU_SCOM_CAPABILITY_START_IDX = 4,
+ PSU_RING_CAPABILITY_START_IDX = 6,
+ PSU_TIMER_CAPABILITY_START_IDX = 8,
+ PSU_MPIPL_CAPABILITY_START_IDX = 10,
+ PSU_SECURITY_CONTROL_CAPABILITY_START_IDX = 12,
+ PSU_GENERIC_CHIPOP_CAPABILITY_START_IDX = 14,
+ // Keep in sync with the spec
+ CAPABILITIES_LAST_INDEX_PSU = 15,
+};
+/**
+ * @brief capabilities enum values.
+ *
+ */
+enum PSU_CAPABILITIES
+{
+ // Capabilities 0, 1
+ PSU_HWP_FFDC_COLLECTION_SUPPORTED = 0xD0000001,
+ PSU_SBE_FFDC_COLLECTION_SUPPORTED = 0xD0000002,
+ PSU_ADDRESS_BLACKLIST_SUPPORTED = 0xD0000004,
+ PSU_HOST_COMMAND_INTERFACE_SUPPORTED = 0xD0000008,
+ PSU_SP_LESS_MPIPL_SUPPORTED = 0xD0000010,
+ PSU_RESERVED_0 = 0xD0000000,
+
+ // Capabilities 2, 3
+ PSU_CONTROL_DEADMAN_LOOP = 0xD1000001,
+ PSU_RESERVED_1 = 0xD1000000,
+
+ // Capabilities 4, 5
+ PSU_EXECUTE_MULTI_SCOM_SUPPORTED = 0xD2000001,
+ PSU_RESERVED_2 = 0xD2000000,
+
+ // Capabilites 6, 7
+ PSU_PUT_RING_FROM_IMAGE_SUPPORTED = 0xD3000001,
+ PSU_RESERVED_3 = 0xD3000000,
+
+ // Capabilities 8, 9
+ PSU_CONTROL_TIMER_SUPPORTED = 0xD4000001,
+ PSU_RESERVED_4 = 0xD4000000,
+
+ // Capabilities 10, 11
+ PSU_GET_ARCHITECTED_REG_SUPPORTED = 0xD5000001,
+ PSU_CLEAR_ARCHITECTED_REG_SUPPORTED = 0xD5000002,
+ PSU_RESERVED_5 = 0xD5000000,
+
+ // Capabilities 12, 13
+ PSU_UNSECURE_MEM_REGION_SUPPORTED = 0xD6000001,
+ PSU_RESERVED_6 = 0xD6000000,
+
+ // Capabilities 14, 15
+ PSU_GET_SBE_FFDC_SUPPPORTED = 0xD7000001,
+ PSU_GET_SBE_CAPABILITIES_SUPPPORTED = 0xD7000002,
+ PSU_READ_SBE_SEEPROM_SUPPORTED = 0xD7000004,
+ PSU_SET_FFDC_ADDRESS_SUPPORTED = 0xD7000008,
+ PSU_QUISCE_SUPPORTED = 0xD7000010,
+ PSU_SET_SYSTEM_FABRIC_ID_MAP_SUPPORTED = 0xD7000020,
+ PSU_STASH_MPIPL_CONFIG_SUPPORTED = 0xD7000040,
+ PSU_RESERVED_7 = 0xD7000000,
+};
+
#endif // __SBEFW_SBE_HOST_INTF_H
diff --git a/src/test/testcases/test.xml b/src/test/testcases/test.xml
index d1bb92c9..6edd31fc 100755
--- a/src/test/testcases/test.xml
+++ b/src/test/testcases/test.xml
@@ -40,6 +40,10 @@
<include>../simics/targets/p9_nimbus/sbeTest/testPutGetMem.xml</include>
<include>../simics/targets/p9_nimbus/sbeTest/testAduMem.xml</include>
<include>../simics/targets/p9_nimbus/sbeTest/testPSUSetFFDCAddr.xml</include>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPSUGetCapabilities.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
<include>../simics/targets/p9_nimbus/sbeTest/testSram.xml</include>
<!-- we want to start hostboot after our memory testcases -->
<testcase>
diff --git a/src/test/testcases/testPSUGetCapabilities.py b/src/test/testcases/testPSUGetCapabilities.py
new file mode 100644
index 00000000..d112259d
--- /dev/null
+++ b/src/test/testcases/testPSUGetCapabilities.py
@@ -0,0 +1,154 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testcases/testPSUGetCapabilities.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2017,2018
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+import sys
+import os
+import struct
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testPSUUtil
+import testRegistry as reg
+import testUtil
+import testMemUtil
+
+def getsingleword(dataInInt):
+ hex_string = '0'*(8-len(str(hex(dataInInt))[2:])) + str(hex(dataInInt))[2:]
+ return list(struct.unpack('<BBBB',hex_string.decode('hex')))
+
+def getdoubleword(dataInInt):
+ hex_string = '0'*(16-len(str(hex(dataInInt))[:18][2:])) + str(hex(dataInInt))[:18][2:]
+ return hex_string
+
+#-------------------------------
+# This is a Test Expected Data
+#-------------------------------
+'''
+Capabilities structure
+'''
+capMsg = (getsingleword(0xD000000F) +
+ getsingleword(0x00) +
+ getsingleword(0xD1000001) +
+ getsingleword(0x0) +
+ getsingleword(0x0) +
+ getsingleword(0x0) +
+ getsingleword(0xD3000001) +
+ getsingleword(0x0) +
+ getsingleword(0xD4000001) +
+ getsingleword(0x0) +
+ getsingleword(0x0) +
+ getsingleword(0x0) +
+ getsingleword(0xD6000001) +
+ getsingleword(0x0) +
+ getsingleword(0xD700007F) +
+ getsingleword(0x0))
+
+def getCapabilities(addr, size, exp_status):
+ # Intialize the class obj instances
+ regObj = testPSUUtil.registry() # Registry obj def for operation
+ '''
+ This data are the values or strings that needs to be validated for the test.
+ '''
+ '''
+#------------------------------------------------------------------------------------------------------------------------------
+# SBE side test data -
+#------------------------------------------------------------------------------------------------------------------------------
+ '''
+ sbe_test_data = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ # Get Capabilities CMD
+ ["write", reg.REG_MBOX0, "0000010000F0D702", 8, "None", "Writing to MBOX0 address"],
+ # Size
+ ["write", reg.REG_MBOX1, getdoubleword(size), 8, "None", "Writing to MBOX1 address"],
+ # Addr
+ ["write", reg.REG_MBOX2, getdoubleword(addr), 8, "None", "Writing to MBOX2 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+
+ #-----------------------------------------------------------------------
+ # Do not modify - Used to simulate interrupt on Ringing Doorbell on Host
+ #-----------------------------------------------------------------------
+ host_polling_data = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.PSU_HOST_DOORBELL_REG_WO_OR, "0", 8, "8000000000000000", "Reading Host Doorbell for Interrupt"],
+ )
+ '''
+#---------------------
+# Host side test data
+#---------------------
+ '''
+ host_test_data = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.REG_MBOX4, "0", 8, getdoubleword((exp_status << 32)+0x00F0D702), "Reading Host MBOX4 data to Validate"],
+ )
+ # HOST->SBE data set execution - Less length setup
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, sbe_test_data )
+ print "\n Poll on Host side for INTR ...\n"
+ #Poll on HOST DoorBell Register for interrupt
+ regObj.pollingOn( testPSUUtil.simSbeObj, host_polling_data, 5 )
+ #SBE->HOST data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, host_test_data )
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+ # Run Simics initially
+ testUtil.runCycles( 100000000 )
+
+ print "\n Execute SBE Test - negative testcase - less size\n"
+ getCapabilities(0x08000000, 30, 0x00020019)
+ print "\n Execute SBE Test - negative testcase - not multiple of PBA\n"
+ getCapabilities(0x08000000, 129, 0x00020019)
+
+ print "\n Execute SBE Test - positive testcase \n"
+ getCapabilities(0x08000000, 128, 0)
+
+ testUtil.runCycles( 100000000 );
+ # read capabilities memory
+ readData = testMemUtil.getmem(0x08000000, 128, 0x02)
+ # ignore first 20 bytes which is a dynamic data
+ readData = readData[28:]
+ # get only valid data
+ readData = readData[:len(capMsg)]
+ if(capMsg == readData):
+ print ("Success - PSU get capabilities")
+ else:
+ print capMsg
+ print readData
+ raise Exception('data mistmach')
+
+if __name__ == "__main__":
+ main()
+ if err:
+ print ( "\nTest Suite completed with error(s)" )
+ #sys.exit(1)
+ else:
+ print ( "\nTest Suite completed with no errors" )
+ #sys.exit(0);
OpenPOWER on IntegriCloud