Skip to content

Commit

Permalink
Support SBE seeprom read
Browse files Browse the repository at this point in the history
Change-Id: I92dfdc5c02867e7c7068b9b0966f3aff76b506ec
RTC: 180510
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48290
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Shakeeb A. Pasha B K <shakeebbk@in.ibm.com>
Reviewed-by: RAJA DAS <rajadas2@in.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
  • Loading branch information
sgupta2m committed Oct 25, 2017
1 parent db75522 commit 204fab9
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 2 deletions.
33 changes: 33 additions & 0 deletions src/sbefw/sbeHostMsg.H
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
/*****************************************************************/
Expand Down
1 change: 1 addition & 0 deletions src/sbefw/sbeHostUtils.C
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/sbefw/sbeMemAccessInterface.H
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/sbefw/sbe_host_intf.H
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/sbefw/sbe_sp_intf.H
Expand Up @@ -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,
};

/**
Expand Down
83 changes: 82 additions & 1 deletion src/sbefw/sbecmdgeneric.C
Expand Up @@ -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,
Expand Down Expand Up @@ -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__

8 changes: 8 additions & 0 deletions src/sbefw/sbecmdgeneric.H
Expand Up @@ -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
5 changes: 5 additions & 0 deletions src/sbefw/sbecmdparser.C
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions src/test/testcases/testGeneric.xml
Expand Up @@ -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>
158 changes: 158 additions & 0 deletions 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);


0 comments on commit 204fab9

Please sign in to comment.