summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/sbefw/sbeHostMsg.H33
-rw-r--r--src/sbefw/sbeHostUtils.C1
-rw-r--r--src/sbefw/sbeMemAccessInterface.H2
-rw-r--r--src/sbefw/sbe_host_intf.H1
-rw-r--r--src/sbefw/sbe_sp_intf.H1
-rw-r--r--src/sbefw/sbecmdgeneric.C83
-rw-r--r--src/sbefw/sbecmdgeneric.H8
-rw-r--r--src/sbefw/sbecmdparser.C5
-rwxr-xr-xsrc/test/testcases/testGeneric.xml4
-rw-r--r--src/test/testcases/testPSUReadSbeMem.py158
10 files changed, 294 insertions, 2 deletions
diff --git a/src/sbefw/sbeHostMsg.H b/src/sbefw/sbeHostMsg.H
index 34d555e6..1b4b7ad3 100644
--- a/src/sbefw/sbeHostMsg.H
+++ b/src/sbefw/sbeHostMsg.H
@@ -36,6 +36,7 @@
#include <stdint.h>
#include "sbe_host_intf.H"
#include "sbe_sp_intf.H"
+#include "sbe_link.H"
/*****************************************************************/
/* SBE->PSU request structures */
@@ -99,6 +100,38 @@ typedef struct
}
} sbeSetFFDCAddrReq_t;
+/* @brief Read SBE MEM structure
+ */
+typedef struct
+{
+ uint64_t offset:32;
+ uint64_t size:32;
+ uint64_t responseAddr;
+
+ // validate request parameters
+ bool validateReq()
+ {
+ // On ppe reading 8 bytes is optimal. So offset
+ // should be multiple of 8.
+ uint32_t const OFFSET_ALLIGNMENT = 8;
+ // As we use PBA operation, size should be multiple
+ // of 128bytes.
+ uint32_t const SIZE_ALLIGNMENT = 128;
+ // There are 4 seeprom devices each of 64KB,
+ // aso there is 1 ecc byte per 8 bytes of data
+ uint32_t const MAX_SEEPROM_SIZE = ((65536 - (65536 % 9)) / 9) * 8 * 4;
+
+ return ( !(( offset % OFFSET_ALLIGNMENT != 0) ||
+ ( size % SIZE_ALLIGNMENT != 0 ) ||
+ ( ( offset + size ) > MAX_SEEPROM_SIZE )) );
+ }
+ // Return effective seeprom address
+ uint64_t * getEffectiveAddr()
+ {
+ return ( uint64_t *)( SBE_SEEPROM_BASE_ORIGIN + offset );
+ }
+} sbeReadMemReq_t;
+
/*****************************************************************/
/* SBE->PSU response structures */
/*****************************************************************/
diff --git a/src/sbefw/sbeHostUtils.C b/src/sbefw/sbeHostUtils.C
index 7cf14f9b..4b1e8a33 100644
--- a/src/sbefw/sbeHostUtils.C
+++ b/src/sbefw/sbeHostUtils.C
@@ -218,6 +218,7 @@ void sbePSUSendResponse(sbeSbe2PsuRespHdr_t &i_sbe2PsuRespHdr,
fapi2::plat_getTargetHandleByChipletNumber<fapi2::TARGET_TYPE_EX>(
sbeMemAccessInterface::PBA_DEFAULT_EX_CHIPLET_ID));
p9_PBA_oper_flag l_myPbaFlag;
+ l_myPbaFlag.setOperationType(p9_PBA_oper_flag::INJ);
sbeMemAccessInterface l_PBAInterface(
SBE_MEM_ACCESS_PBA,
diff --git a/src/sbefw/sbeMemAccessInterface.H b/src/sbefw/sbeMemAccessInterface.H
index 6e268b01..fb01ff5d 100644
--- a/src/sbefw/sbeMemAccessInterface.H
+++ b/src/sbefw/sbeMemAccessInterface.H
@@ -86,7 +86,7 @@ class sbeMemAccessInterface
// Granule size based on interface - PBA/ADU
uint32_t iv_granuleSize;
// Buffer size is bigger of the two granules
- char iv_buffer[MEM_INTERFACE_SIZE_BYTES];
+ char iv_buffer[MEM_INTERFACE_SIZE_BYTES] __attribute__ ((aligned (8)));
// Interface cleaned up - indicates if the underlying
// HWP cleanup is done for the interface.
// A new object assumes interface is in cleaned up
diff --git a/src/sbefw/sbe_host_intf.H b/src/sbefw/sbe_host_intf.H
index 378acae0..ed119bc9 100644
--- a/src/sbefw/sbe_host_intf.H
+++ b/src/sbefw/sbe_host_intf.H
@@ -96,6 +96,7 @@ enum sbePsuUpdateMemoryRegionMessages
*/
enum sbePsuGenericMessages
{
+ SBE_PSU_GENERIC_MSG_READ_SBE_MEM = 0x03,
SBE_PSU_GENERIC_MSG_SET_FFDC_ADDR = 0x04,
SBE_PSU_GENERIC_MSG_QUIESCE = 0x05,
SBE_PSU_GENERIC_MSG_SYSTEM_FABRIC_MAP = 0x06,
diff --git a/src/sbefw/sbe_sp_intf.H b/src/sbefw/sbe_sp_intf.H
index c1cf688d..8d76772a 100644
--- a/src/sbefw/sbe_sp_intf.H
+++ b/src/sbefw/sbe_sp_intf.H
@@ -217,6 +217,7 @@ enum sbeSecondaryResponse
SBE_SEC_MAXIMUM_MEM_REGION_EXCEEDED = 0x16,
SBE_SEC_MEM_REGION_AMEND_ATTEMPTED = 0x17,
SBE_SEC_INPUT_BUFFER_OVERFLOW = 0x18,
+ SBE_SEC_INVALID_PARAMS = 0x19,
};
/**
diff --git a/src/sbefw/sbecmdgeneric.C b/src/sbefw/sbecmdgeneric.C
index 5c7320b4..1e0655aa 100644
--- a/src/sbefw/sbecmdgeneric.C
+++ b/src/sbefw/sbecmdgeneric.C
@@ -204,7 +204,7 @@ uint32_t sbeGetFfdc (uint8_t *i_pArg)
// @TODO via RTC : 149074
// primary and secondary status should be picked
// from the globals.
- // Check for Primary and Secondary Status from Globals and then send
+ // Check for Primary and Secondary Status from Globals and then send
// internal FFDC.
rc = sbeFfdcPack.sendOverFIFO(respHdr,
SBE_FFDC_ALL_DUMP,
@@ -442,5 +442,86 @@ uint32_t sbePsuQuiesce( uint8_t *i_pArg )
return rc;
#undef SBE_FUNC
}
+
+//----------------------------------------------------------------------------
+uint32_t sbeReadMem( uint8_t *i_pArg )
+{
+ #define SBE_FUNC "sbeReadMem"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t fapiRc = FAPI2_RC_SUCCESS;
+ sbeReadMemReq_t req = {};
+
+ do
+ {
+ // Extract the request
+ // and send Ack to Host via SBE_SBE2PSU_DOORBELL_SET_BIT1
+ rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ (sizeof(req)/sizeof(uint64_t)),
+ (uint64_t*)&req,
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != rc)
+ {
+ SBE_ERROR(SBE_FUNC "Failed to extract SBE_HOST_PSU_MBOX_REG1 and "
+ "SBE_HOST_PSU_MBOX_REG2");
+ break;
+ }
+
+ if(!( req.validateReq()) )
+ {
+ SBE_ERROR(SBE_FUNC"Invalid data. offset:0x%08X size:0x%08X",
+ req.offset, req.size );
+ SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(SBE_PRI_USER_ERROR,
+ SBE_SEC_INVALID_PARAMS);
+ break;
+ }
+
+ // Default EX Target Init. As its not LCO mode, ex does not matter.
+ fapi2::Target<fapi2::TARGET_TYPE_EX> l_ex(
+ fapi2::plat_getTargetHandleByChipletNumber<fapi2::TARGET_TYPE_EX>(
+ sbeMemAccessInterface::PBA_DEFAULT_EX_CHIPLET_ID));
+ p9_PBA_oper_flag l_myPbaFlag;
+ l_myPbaFlag.setOperationType(p9_PBA_oper_flag::INJ);
+
+ sbeMemAccessInterface pbaInterface(
+ SBE_MEM_ACCESS_PBA,
+ req.responseAddr,
+ &l_myPbaFlag,
+ SBE_MEM_ACCESS_WRITE,
+ sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES,
+ l_ex);
+ uint32_t len = req.size;
+ uint64_t *seepromAddr = req.getEffectiveAddr();
+ while( len > 0)
+ {
+ uint64_t *dataBuffer = static_cast<uint64_t*>
+ (pbaInterface.getBuffer());
+ for(size_t idx=0;
+ idx < (sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES/
+ sizeof(uint64_t));
+ idx++)
+ {
+ *dataBuffer = *seepromAddr;
+ dataBuffer++;
+ seepromAddr++;
+ }
+
+ fapi2::ReturnCode fapiRc = pbaInterface.accessGranule(
+ len == sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES);
+ if( fapiRc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ len = len - sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES;
+ }
+ } while(false);
+
+ // Send the response
+ sbePSUSendResponse(SBE_GLOBAL->sbeSbe2PsuRespHdr, fapiRc, rc);
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
#endif //not __SBEFW_SEEPROM__
diff --git a/src/sbefw/sbecmdgeneric.H b/src/sbefw/sbecmdgeneric.H
index 934d34a6..af14541f 100644
--- a/src/sbefw/sbecmdgeneric.H
+++ b/src/sbefw/sbecmdgeneric.H
@@ -156,4 +156,12 @@ uint32_t sbeSetSystemFabricMap(uint8_t *i_pArg);
*/
uint32_t sbeStashKeyAddrPair(uint8_t *i_pArg);
+/**
+ * @brief Read the data from SBE memory (0xD703)
+ *
+ * @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 sbeReadMem(uint8_t *i_pArg);
#endif // __SBEFW_SBECMDGENERIC_H
diff --git a/src/sbefw/sbecmdparser.C b/src/sbefw/sbecmdparser.C
index af7b51bb..67c5e166 100644
--- a/src/sbefw/sbecmdparser.C
+++ b/src/sbefw/sbecmdparser.C
@@ -295,6 +295,11 @@ static sbeCmdStruct_t g_sbePsuMemRegionCmdArray[] =
//////////////////////////////////////////////////////////////
static sbeCmdStruct_t g_sbePsuGenericCmdArray[] =
{
+ {sbeReadMem,
+ SBE_PSU_GENERIC_MSG_READ_SBE_MEM,
+ (uint16_t)(~SBE_FENCE_AT_RUNTIME),
+ },
+
{sbeSetFFDCAddr,
SBE_PSU_GENERIC_MSG_SET_FFDC_ADDR,
SBE_NO_FENCE,
diff --git a/src/test/testcases/testGeneric.xml b/src/test/testcases/testGeneric.xml
index dad7a81b..13e6eae6 100755
--- a/src/test/testcases/testGeneric.xml
+++ b/src/test/testcases/testGeneric.xml
@@ -37,3 +37,7 @@
<simcmd>run-python-file targets/p9_nimbus/sbeTest/testHostFFDC.py</simcmd>
<exitonerror>yes</exitonerror>
</testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPSUReadSbeMem.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
diff --git a/src/test/testcases/testPSUReadSbeMem.py b/src/test/testcases/testPSUReadSbeMem.py
new file mode 100644
index 00000000..a91fbc48
--- /dev/null
+++ b/src/test/testcases/testPSUReadSbeMem.py
@@ -0,0 +1,158 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testcases/testPSUReadSbeMem.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2017
+# [+] 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
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testPSUUtil
+import testRegistry as reg
+import testUtil
+import testMemUtil
+
+#-------------------------------
+# This is a Test Expected Data
+#-------------------------------
+def getdoubleword(dataInInt):
+ hex_string = '0'*(16-len(str(hex(dataInInt))[:18][2:])) + str(hex(dataInInt))[:18][2:]
+ return hex_string
+
+def readSeeprom(offset, size, destAddr, primStatus, secStatus):
+ '''
+ #------------------------------------------------------------------------------------------------------------------------------
+ # SBE side test data -
+ #------------------------------------------------------------------------------------------------------------------------------
+ '''
+ sbe_test_data = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ # FFDC Size, Pass CMD Size
+ ["write", reg.REG_MBOX0, "0000010000F0D703", 8, "None", "Writing to MBOX0 address"],
+ # seeprom offset, Size
+ ["write", reg.REG_MBOX1, getdoubleword((offset<<32)+size), 8, "None", "Writing to MBOX1 address"],
+ # response Addr
+ ["write", reg.REG_MBOX2, getdoubleword(destAddr), 8, "None", "Writing to MBOX2 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+ '''
+ #---------------------
+ # Host side test data - SUCCESS
+ #---------------------
+ '''
+ host_test_data_success = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.REG_MBOX4, "0", 8, getdoubleword((primStatus<<48)+(secStatus<<32)+0xF0D703), "Reading Host MBOX4 data to Validate"],
+ )
+
+ '''
+ #-----------------------------------------------------------------------
+ # 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 Bit0"],
+ )
+ # Run Simics initially
+ testUtil.runCycles( 10000000 );
+
+ # Intialize the class obj instances
+ regObj = testPSUUtil.registry() # Registry obj def for operation
+
+ # HOST->SBE data set execution
+ 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_success )
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+ # Run Simics initially
+ testUtil.runCycles( 10000000 );
+
+ print "\n Execute SBE Test - Read SBE Mem\n"
+
+ '''
+ Test Case 1
+ '''
+ readSeeprom(0, 128, 0x08000000, 0, 0)
+ print "SUCCESS: read seeprom valid"
+
+ # Read data from cache and verify its contents
+ # seeprom header
+ seepprmHdr = 'XIP SEPM'
+ #read from cache
+ readData = testMemUtil.getmem(0x08000000, 0x80, 0x02)
+
+ for byte in range(len(seepprmHdr)):
+ if( ord(seepprmHdr[byte]) != readData[byte ]):
+ print "Data mismtach at: ", byte ;
+ print " expected: ", ord(seepprmHdr[byte]);
+ print " Actual: ", readData[byte];
+ raise Exception('data mistmach');
+
+ '''
+ Test Case 2
+ '''
+ readSeeprom(0x38CA0, 0x180, 0x8973780, 0, 0)
+ print "SUCCESS: read seeprom HB testcase"
+
+ '''
+ Test Case 3
+ '''
+ readSeeprom(0x0, 0x40, 0x08000000, 0x03, 0x19)
+ print "SUCCESS: read seeprom size not aligned"
+
+ '''
+ Test Case 4
+ '''
+ readSeeprom(0x3fe80, 0x180, 0x08000000, 0x03, 0x19)
+ print "SUCCESS: read seeprom size exceeded"
+
+ '''
+ Test Case 5
+ '''
+ readSeeprom(0x7, 0x40, 0x08000000, 0x03, 0x19)
+ print "SUCCESS: read seeprom offset not aligned"
+
+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