From eb1b71efed5605274dbfb17a11e353a385e190b0 Mon Sep 17 00:00:00 2001 From: Raja Das Date: Tue, 15 Mar 2016 23:44:39 -0500 Subject: ADU Support Change-Id: I8351391d75fcd0d8d07e94d2e3378d052993c3a7 RTC: Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22855 Tested-by: Jenkins Server Reviewed-by: Sachin Gupta Reviewed-by: AMIT J. TENDOLKAR --- sbe/build/citest/etc/patches/chip.act.patch | 146 ++++- sbe/sbefw/sbeSpMsg.H | 107 ++- sbe/sbefw/sbe_sp_intf.H | 15 +- sbe/sbefw/sbecmdmemaccess.C | 831 ++++++++++++++++++------ sbe/sbefw/sbecmdmemaccess.H | 1 - sbe/test/test.xml | 1 + sbe/test/testAduMem.xml | 19 + sbe/test/testAduMem_ecc.py | 45 ++ sbe/test/testAduMem_itag.py | 43 ++ sbe/test/testAduMem_noEccNoItag.py | 76 +++ sbe/test/testAduMem_withEccItag.py | 43 ++ sbe/test/testAduMem_withEccWithItagReadWrite.py | 73 +++ 12 files changed, 1153 insertions(+), 247 deletions(-) create mode 100644 sbe/test/testAduMem.xml create mode 100644 sbe/test/testAduMem_ecc.py create mode 100644 sbe/test/testAduMem_itag.py create mode 100644 sbe/test/testAduMem_noEccNoItag.py create mode 100644 sbe/test/testAduMem_withEccItag.py create mode 100644 sbe/test/testAduMem_withEccWithItagReadWrite.py (limited to 'sbe') diff --git a/sbe/build/citest/etc/patches/chip.act.patch b/sbe/build/citest/etc/patches/chip.act.patch index 4e47f2fc..0b9cf0f0 100644 --- a/sbe/build/citest/etc/patches/chip.act.patch +++ b/sbe/build/citest/etc/patches/chip.act.patch @@ -1,2 +1,146 @@ -265a266 +184,240c184 +< # ========================================================================== +< # Actions for p9_adu_access and p9_adu_setup procedures +< # ========================================================================== +< #If a read/write is done to the ALTD_DATA Register set the ALTD_STATUS Register so things are as expected +< CAUSE_EFFECT{ +< LABEL=[ADU Read or write to set ALTD_STATUS Register] +< #If the data register is read +< WATCH_READ=[REG(0x00090004)] +< #If the data register is written +< WATCH=[REG(0x00090004)] +< +< #Set the ALTD_STATUS Register so these bits are set: +< #FBC_ALTD_BUSY = WAIT_CMD_ARBIT = WAIT_RESP = OVERRUN_ERR = AUTOINC_ERR = COMMAND_ERR = ADDRESS_ERR = COMMAND_HANG_ERR = DATA_HANG_ERR = PBINIT_MISSING = ECC_CE = ECC_UE = ECC_SUE = 0 +< EFFECT: TARGET=[REG(0x00090003)] OP=[BUF,AND] DATA=[LITERAL(64,001FDFFF FFFF1FFF)] +< EFFECT: TARGET=[REG(0x00090003)] OP=[BUF,OR] DATA=[LITERAL(64,30000000 00000000)] +< } +< +< #If a read/write is done to the ALTD_DATA Register and the Address only bit is not set then set the DATA_DONE bit to 1 +< CAUSE_EFFECT{ +< LABEL=[ADU Read or write to set ALTD_STATUS[DATA_DONE] bit] +< #If the data register is read +< WATCH_READ=[REG(0x00090004)] +< #If the data register is written +< WATCH=[REG(0x00090004)] +< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] +< +< #Set the DATA_DONE bit +< EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] +< } +< +< #If a read/write is done to the ALTD_DATA Register and the Data only bit is not set then set the ADDR_DONE bit to 1 +< CAUSE_EFFECT{ +< LABEL=[ADU Read or write to set ALTD_STATUS[ADDR_DONE] bit] +< #If the data register is read +< WATCH_READ=[REG(0x00090004)] +< #If the data register is written +< WATCH=[REG(0x00090004)] +< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] +< +< #Set the ADDR_DONE bit +< EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] +< } +< +< #If a read is done to the ALTD_CMD Register and it sets the lock set the ALTD_STATUS Register so the ALTD_STATUS_BUSY bit is set +< CAUSE_EFFECT{ +< LABEL=[ADU Write to set ALTD_STATUS_BUSY] +< WATCH=[REG(0x00090001)] +< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[11] +< +< #Set the ALTD_STATUS Register so the ALTD_STATUS_BUSY bit is set +< EFFECT: TARGET=[REG(0x090003)] OP=[BIT,ON] BIT=[0] +< } +< #If a write is done to the ALD_CMD_REG to set the FBC_ALTD_START_OP bit it should turn FBC_ALTD_BUSY off +< CAUSE_EFFECT{ +< LABEL=[ADU Write to ALTD_CMD_REG to unset set ALTD_STATUS FBC_ALTD_BUSY bit] +< WATCH=[REG(0x00090001)] +< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] +--- +> ### ADU ACTIONS - READ WRITE RESET ### +242,243c186,265 +< #Unset the ALTD_STATUS Register so the ALTD_STATUS_BUSY is unset +< EFFECT: TARGET=[REG(0x090003)] OP=[BIT,OFF] BIT=[0] +--- +> # Reset ALTD Status Reg +> CAUSE_EFFECT { +> LABEL=[RESET FSM ALTD Status Register] +> WATCH=[REG(0x00090001)] # ALTD_Cmd_Reg +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[4] #Reset FSM bit +> EFFECT: TARGET=[REG(0x00090003)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000000)] +> } +> +> # ADU Transaction Complete Status - Busy Bit Low +> CAUSE_EFFECT { +> LABEL=[ALTD_BUSY Status Register Clear] +> WATCH=[REG(0x00090003)] # ALTD_Status_Reg +> CAUSE: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE +> CAUSE: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[19] #AUTO INCR Mode OFF +> +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,OFF] BIT=[0] #BUSY Bit low +> } +> +> # Read without AutoIncr +> CAUSE_EFFECT{ +> LABEL=[READ Mainstore without AutoIncr] +> WATCH=[REG(0x00090001)] # ALTD_Cmd_Reg +> +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[5] #READ ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data +> +> EFFECT: TARGET=[MODULE(readMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # read the memory +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE +> } +> +> # Read with AutoIncr +> CAUSE_EFFECT{ +> LABEL=[READ Mainstore with AutoIncr] +> WATCH_READ=[REG(0x00090004)] # ALTD_Data_reg +> +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[5] #READ ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[19] #AutoInc bit on +> +> EFFECT: TARGET=[MODULE(readMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # read the memory +> EFFECT: TARGET=[REG(0x00090000)] OP=[INCREMENT,MASK] INCVAL=[8] MASK=[LITERAL(64,00000000 0000FFFF)] # incr addr reg by 8 +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE +> } +> +> # Write without AutoIncr +> CAUSE_EFFECT{ +> LABEL=[WRITE Mainstore without AutoIncr] +> WATCH=[REG(0x00090001)] # ALTD_Cmd_Reg +> WATCH=[REG(0x00090004)] # ALTD_Data_reg +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[5] #WRITE ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[19] #AutoInc bit off +> EFFECT: TARGET=[MODULE(writeMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # write the memory +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE +> } +> +> # Write with AutoIncr +> CAUSE_EFFECT{ +> LABEL=[WRITE Mainstore with AutoIncr] +> WATCH=[REG(0x00090001)] # ALTD_Cmd_reg +> WATCH=[REG(0x00090004)] # ALTD_Data_reg +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[5] #WRITE ADU Operation +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data +> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[19] #AutoInc bit on +> EFFECT: TARGET=[MODULE(writeMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # write the memory +> EFFECT: TARGET=[REG(0x00090000)] OP=[INCREMENT,MASK] INCVAL=[8] MASK=[LITERAL(64, 00000000 0000FFFF)] # incr addr reg by 8 +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE +> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE +265a288 > EFFECT: TARGET=[MODULE(executeInstruction, MYCORE)] OP=[MODULECALL] DATA=[REG(MYCHIPLET, 0x00010A4F)] diff --git a/sbe/sbefw/sbeSpMsg.H b/sbe/sbefw/sbeSpMsg.H index df2730cb..3bb54c00 100644 --- a/sbe/sbefw/sbeSpMsg.H +++ b/sbe/sbefw/sbeSpMsg.H @@ -295,20 +295,65 @@ typedef struct */ typedef struct { - uint32_t flags; // Operational Flags - uint32_t addrHi; // Higher 32-Bit Memory Address - uint32_t addrLo; // Lower 32-Bit Memory Address - uint32_t len; // Length of Data in Bytes + uint32_t coreChipletId:8; //Pervasive Core Chiplet Id for PBA + uint32_t eccByte:8; //Ecc Override Byte from user + uint32_t flags:16; //Operational Flags -refer enum sbeMemoryAccessFlags + uint32_t addrHi; //Higher 32-Bit Memory Address + uint32_t addrLo; //Lower 32-Bit Memory Address + uint32_t len; //Length of Data in Bytes /** - * @brief Calculates 64-bit PBA Address + * @brief Calculates 64-bit PBA ADU Address * - * @return Return 64-bit PBA address + * @return Return 64-bit PBA ADU address */ - uint64_t getPbaAddr() + uint64_t getAddr() const { - uint64_t addr = ((uint64_t)addrHi << 32) | addrLo; - return addr; + return (((uint64_t)addrHi << 32) | addrLo); + } + + /** + * @brief Determines if ECC Override bit is set + * + * @return Returns True if ECC Override bit is set + * False if ECC Override bit is not set + */ + bool isEccOverrideFlagSet() const + { + return ((flags & SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE) ? true : false); + } + + /** + * @brief Determines if ECC required bit is set + * + * @return Returns True if ECC required flag is set + * False if ECC required flag is not set + */ + bool isEccFlagSet() const + { + return ((flags & SBE_MEM_ACCESS_FLAGS_ECC_REQUIRED) ? true : false); + } + + /** + * @brief Determines if Itag required bit is set + * + * @return Returns True if Itag required flag is set + * False if Itag required flag is not set + */ + bool isItagFlagSet() const + { + return ((flags & SBE_MEM_ACCESS_FLAGS_ITAG) ? true : false); + } + + /** + * @brief Determines if Cache Inhibited mode is set + * + * @return Returns True if Cache Inhibited Mode flag is set + * False if Cache Inhibited Mode flag is not set + */ + bool isCacheInhibitModeFlagSet() const + { + return ((flags & SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT) ? true : false); } /** @@ -319,9 +364,7 @@ typedef struct */ bool isPbaFlagSet() { - bool tmp_flag = (flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA) ? - true : false ; - return tmp_flag; + return ((flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA) ? true : false); } /** @@ -330,11 +373,9 @@ typedef struct * @return Returns True if Auto Increment mode is set * False if Auto Increment is not set */ - bool isAutoIncrModeSet() + bool isAutoIncrModeSet() const { - bool tmp_flag = (flags & SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON) ? - true : false ; - return tmp_flag; + return ((flags & SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON) ? true : false); } /** @@ -343,25 +384,39 @@ typedef struct * @return Returns True if Fast mode is set * False if Fast mode is not set */ - uint32_t isFastModeSet() + uint32_t isFastModeSet() const { - uint32_t tmp_flag = (flags & SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON) ? - (1<<31) : 0; - return tmp_flag; + return ((flags & SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON) ? true : false); } /** - * @brief Calculates Data length in alignment with PBA Cacheline (128B) + * @brief Determines if LCO Mode is set * - * @return Returns Data length in alignment with PBA Cacheline + * @return Returns True if LCO mode is set + * False if LCO mode is not set */ - uint64_t getDataLenPbaCacheAlign() + uint32_t isPbaLcoModeSet() const { - uint64_t l_len = (len / 8) / 16; + return ((flags & SBE_MEM_ACCESS_FLAGS_LCO_ENABLED) ? true : false); + } + + /** + * @brief Calculates Data length in alignment with PBA/ADU Cacheline + * (128B/8B respectively) + * + * @return Returns Data length in alignment with PBA/ADU Cacheline + */ + uint64_t getDataLenCacheAlign() const + { + uint64_t l_len = (len / 8); + if(flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA) + { + l_len = (l_len / 16); + } return l_len; } -}sbeMemAccessReqMsgHdr_t; +}sbeMemAccessReqMsgHdr_t; /** * @brief Structure for SBE OCC Get/Put Sram Access ChipOps (0xA403/A404) @@ -438,7 +493,7 @@ typedef struct "mode[%d] ThreadNum[%d]", threadOps, mode, threadNum); l_validatePassFlag = false; } - return l_validatePassFlag; + return l_validatePassFlag; } /** diff --git a/sbe/sbefw/sbe_sp_intf.H b/sbe/sbefw/sbe_sp_intf.H index 62894b6a..531a72eb 100644 --- a/sbe/sbefw/sbe_sp_intf.H +++ b/sbe/sbefw/sbe_sp_intf.H @@ -269,12 +269,15 @@ enum */ enum sbeMemoryAccessFlags { - SBE_MEM_ACCESS_FLAGS_TARGET_PROC = 0x00000001, - SBE_MEM_ACCESS_FLAGS_TARGET_PBA = 0x00000002, - SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON = 0x00000004, - SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE = 0x00000008, - SBE_MEM_ACCESS_FLAGS_TAG = 0x00000010, - SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON = 0x00000020, + SBE_MEM_ACCESS_FLAGS_TARGET_PROC = 0x0001, //required in ADU + SBE_MEM_ACCESS_FLAGS_TARGET_PBA = 0x0002, //required in PBA + SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON = 0x0004, + SBE_MEM_ACCESS_FLAGS_ECC_REQUIRED = 0x0008, //required only in ADU-GET + SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE = 0x0008, //required only in ADU-PUT + SBE_MEM_ACCESS_FLAGS_ITAG = 0x0010, //ITAG Mode in ADU + SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON = 0x0020, + SBE_MEM_ACCESS_FLAGS_LCO_ENABLED = 0x0040, //required only in PBA-PUT + SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT = 0x0080, //required in I/O oper ADU }; /** diff --git a/sbe/sbefw/sbecmdmemaccess.C b/sbe/sbefw/sbecmdmemaccess.C index 6a55e66c..790e4c94 100644 --- a/sbe/sbefw/sbecmdmemaccess.C +++ b/sbe/sbefw/sbecmdmemaccess.C @@ -13,25 +13,245 @@ #include "fapi2.H" -#include "p9_pba_access.H" #include "p9_pba_setup.H" +#include "p9_adu_setup.H" +#include "p9_pba_access.H" +#include "p9_adu_access.H" + using namespace fapi2; +// Buffer requirement for ADU and PBA on the stack +static const uint32_t MAX_ADU_BUFFER = 40; +static const uint32_t MAX_PBA_BUFFER = 32; +// PBA / ADU Granule size as per the HWP Requirement +static const uint32_t PBA_GRAN_SIZE_BYTES = 128; +static const uint32_t ADU_GRAN_SIZE_BYTES = 8; + +// Multiplier factor with respect to the FIFO length +static const uint32_t ADU_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT = 2; +static const uint32_t PBA_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT = 32; + +//Default EX Target ChipletId to be used in PBA by default +static const uint32_t PBA_DEFAULT_EX_CHIPLET_ID = 7; + +/** + * @brief static definition of parameters passed in adu chip-ops + */ +static const uint32_t SBE_ADU_LOCK_TRIES = 3; + +// Transaction size (choice is 1, 2, 4, or 8) +// 0b00: TSIZE_1 +// 0b01: TSIZE_2 +// 0b10: TSIZE_4 +// 0b11: TSIZE_8 +static const uint32_t SBE_ADU_TRANSACTION_SIZE = 3; +static const bool SBE_ADU_LEAVE_DIRTY_BOOL = false; +static const bool SBE_ADU_LOCK_PICK_BOOL = false; + +/** + * @brief Mask used to build the Flag struct for ADU chip-op + **/ +static const uint32_t ADU_LOCK_TRIES_SHIFT = 16; +static const uint32_t ADU_TRANSACTION_SIZE_SHIFT = 20; +static const uint32_t ADU_ECC_OVERRIDE_BIT_SHIFT = 22; +static const uint32_t ADU_ECC_REQUIRED_BIT_SHIFT = 23; +static const uint32_t ADU_ITAG_REQUIRED_BIT_SHIFT = 24; +static const uint32_t ADU_FAST_MODE_SHIFT = 25; +static const uint32_t ADU_LEAVE_DIRTY_SHIFT = 26; +static const uint32_t ADU_LOCK_PICK_SHIFT = 27; +static const uint32_t ADU_AUTO_INCR_SHIFT = 28; +static const uint32_t CACHE_INHIBIT_MODE_SHIFT = 29; + +// Fast Mode bit shift for PBA +static const uint32_t PBA_FAST_MODE_SHIFT = 31; + +// Macros Defined for Internal RC Check, Break if Error +#define checkSbeRC(l_rc) \ +if ((l_rc) != SBE_SEC_OPERATION_SUCCESSFUL) \ +{ \ + break; \ +} \ + /////////////////////////////////////////////////////////////////////// -// @brief sbeMemAccess_Wrap Memory Access Wrapper function +// @brief align4ByteWordLength - Internal Method to this file +// Align the length passed and return number of words // -// @param [in] i_flagGetOrPut Flag to indicate the memory Access Type -// true : GetMem ChipOp -// false : PutMem ChipOp +// @param [in] i_len, length pass from user in Bytes +// +// @return Number of words (number of 4byte length) +/////////////////////////////////////////////////////////////////////// +inline uint32_t align4ByteWordLength(uint32_t i_len) +{ + if(i_len % 4 != 0) + { + i_len = i_len + (4 - (i_len % 4)); + } + return(i_len/4); +} + +/////////////////////////////////////////////////////////////////////// +// @brief calInterAduLenForUpFifo - Internal Method to this file +// Calculate Intermediate Adu Data length for Upstream Fifo +// +// @param [in] i_mod, Modulus number from user, (from numGranules % 4) +// could be any values from 1,2,3 +// @param [in] i_itag, Itag flag +// @param [in] i_ecc, Ecc flag +// +// @return length in bytes for intermediate ADU length +/////////////////////////////////////////////////////////////////////// +inline uint32_t calInterAduLenForUpFifo(uint8_t i_mod, bool i_itag, bool i_ecc) +{ + //Default init length with either Ecc or Itag + uint32_t l_len = + ((ADU_GRAN_SIZE_BYTES + 1) * (1 + i_mod)); + // If ECC and iTag bit is also part of the buffer + if(i_itag && i_ecc) + { + l_len = l_len + (1 + i_mod); + } + return (l_len); +} + +/////////////////////////////////////////////////////////////////////// +// @brief sbeAduLenInUpStreamFifo - Internal Method to this file +// Calculate the Final Size which is write/read to/from HWP +// +// @param [in] i_numGranules, Number of granules read/write +// @param [in] i_itag, Itag flag +// @param [in] i_ecc, Ecc flag +// +// @return Length in bytes for ADU to be put in Upstream FIFO +/////////////////////////////////////////////////////////////////////// +inline uint32_t sbeAduLenInUpStreamFifo(uint32_t i_numGranules, + bool i_itag, + bool i_ecc) +{ + uint32_t l_respLen = i_numGranules * ADU_GRAN_SIZE_BYTES; + if(i_itag) + { + // Add one byte for Itag for Each Granule Completed + l_respLen = l_respLen + i_numGranules; + } + if(i_ecc) + { + // Add one byte for Ecc for Each Granule Completed + l_respLen = l_respLen + i_numGranules; + } + return l_respLen; +} + +/////////////////////////////////////////////////////////////////////// +// @brief flushUpstreamFifo - Internal Method to this file, to flush +// out the upstream fifo +// +// @param [in] i_fapiRc, Fapi RC // // @return RC from the underlying FIFO utility /////////////////////////////////////////////////////////////////////// -uint32_t sbeMemAccess_Wrap(const bool i_flagGetOrPut) +inline uint32_t flushUpstreamFifo (const uint32_t &i_fapiRc) { - #define SBE_FUNC " sbeMemAccess_Wrap " - SBE_ENTER(SBE_FUNC); + uint32_t l_len2dequeue = 0; + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + if ( i_fapiRc != FAPI2_RC_SUCCESS ) + { + l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, + true, true); + } + // For other success paths, just attempt to offload + // the next entry, which is supposed to be the EOT entry + else + { + l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true); + } + return l_rc; +} + + +/////////////////////////////////////////////////////////////////////// +// @brief constructAduFlag - Internal Method to this file, to construct +// ADU flag as the HWP expects +// +// @param [in] i_hdr, Message Request Header +// @param [in] i_isFlagRead, Read/Write Flag +// +// @return Constructed ADU Flag +/////////////////////////////////////////////////////////////////////// +uint32_t constructAduFlag(const sbeMemAccessReqMsgHdr_t & i_hdr, + const bool i_isFlagRead) +{ + #define SBE_FUNC " constructAduFlag" + + // Fast Mode / Ecc mode / Cache Inhibit Mode / Auto Increment + // required in ADU operations. + bool l_isFastMode = i_hdr.isFastModeSet(); + bool l_isCacheInhibitMode = i_hdr.isCacheInhibitModeFlagSet(); + bool l_isItagBit = i_hdr.isItagFlagSet(); + bool l_isAutoIncr = i_hdr.isAutoIncrModeSet(); + bool l_isEccRequiredMode = false; + bool l_isEccOverrideMode = false; + + if(!i_isFlagRead) // ECC override in write mode + { + l_isEccOverrideMode = i_hdr.isEccOverrideFlagSet(); + if(l_isEccOverrideMode) + { + l_isEccRequiredMode = true; + } + } + else // ECC required in read mode + { + l_isEccRequiredMode = i_hdr.isEccFlagSet(); + } + + // Construct the flag required for adu setup + uint32_t l_aduSetupFlag = + ( (l_isCacheInhibitMode << CACHE_INHIBIT_MODE_SHIFT) | + // 3-bit of Cache mode placed in 31-30-29 bits + (l_isAutoIncr << ADU_AUTO_INCR_SHIFT) | + // 1-bit Auto increment placed at 28th bit + (SBE_ADU_LOCK_PICK_BOOL << ADU_LOCK_PICK_SHIFT) | + // 1-bit pick lock placed at 27th bit + (SBE_ADU_LEAVE_DIRTY_BOOL << ADU_LEAVE_DIRTY_SHIFT) | + // 1-bit leave dirty placed at 26th bit + (l_isFastMode << ADU_FAST_MODE_SHIFT) | + // 1-bit Fast mode placed at 25th bit + (l_isItagBit << ADU_ITAG_REQUIRED_BIT_SHIFT) | + // 1-bit itag placed at 24th bit + (l_isEccRequiredMode << ADU_ECC_REQUIRED_BIT_SHIFT) | + // 1-bit ecc required at 23rd bit + (l_isEccOverrideMode << ADU_ECC_OVERRIDE_BIT_SHIFT) | + // 1-bit ecc override at 22nd bit + (SBE_ADU_TRANSACTION_SIZE << ADU_TRANSACTION_SIZE_SHIFT) | + // 2-bit Transcation size at 21-20th bits + (SBE_ADU_LOCK_TRIES << ADU_LOCK_TRIES_SHIFT) ); + // 4-bit Lock Tries at 19-18-17-16 bits + + SBE_DEBUG(SBE_FUNC "Cache[%d] Itag[%d] AutoIncr[%d] FastMode[%d] ", + l_isCacheInhibitMode,l_isItagBit,l_isAutoIncr,l_isFastMode); + SBE_DEBUG(SBE_FUNC "EccRequiredMode[%d] EccOverrideMode[%d] EccOverrideByte" + "[0x%02X] AduSetupFlag[0x%04X]",l_isEccRequiredMode,l_isEccOverrideMode, + i_hdr.eccByte, l_aduSetupFlag); + + return (l_aduSetupFlag); + #undef SBE_FUNC +} +/////////////////////////////////////////////////////////////////////// +// @brief processPbaRequest - Internal Method to this file, +// To process the PBA Access request +// +// @param [in] i_hdr, Message Request Header +// @param [in] i_isFlagRead, Read/Write Flag +// +// @return RC from the method +/////////////////////////////////////////////////////////////////////// +uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, + const bool i_isFlagRead) +{ + #define SBE_FUNC " processPbaRequest " + SBE_ENTER(SBE_FUNC); uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; ReturnCode l_fapiRc = FAPI2_RC_SUCCESS; @@ -39,194 +259,391 @@ uint32_t sbeMemAccess_Wrap(const bool i_flagGetOrPut) l_respHdr.init(); sbeResponseFfdc_t l_ffdc; - // Create an instance of Memory Access ChipOp structure - sbeMemAccessReqMsgHdr_t l_req = {0}; - - // @TODO via RTC: 128982 - // ADU support - // Handle ECC data - - // Offload the common header from - // the Upstream FIFO - bool l_eot = (i_flagGetOrPut)? true : false; - uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t); - l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_req, l_eot); - - SBE_DEBUG(SBE_FUNC " flags[0x%08X], addrHi[0x%08X]," - " addrLo[0x%08X], len[[0x%08X]", - l_req.flags, l_req.addrHi, - l_req.addrLo, l_req.len); + // Default for PBA + uint32_t l_sizeMultiplier = PBA_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT; + uint32_t l_granuleSize = PBA_GRAN_SIZE_BYTES; + uint64_t l_addr = i_hdr.getAddr(); - // Calculate the PBA address from the given input - uint64_t l_pbaAddr = l_req.getPbaAddr(); - - // @TODO via RTC: 128982 - // Handle Invalid length (0) and Invalid Flags: - // Primary status code could be SBE_PRI_INVALID_DATA, - // but, what would be the secondary status code? - - // @TODO via RTC: 128982 - // ADU support - // Auto Increment Flag is applicable only for ADU operations - // bool l_isAutoIncr = l_req.isAutoIncrModeSet(); + // Proc Chip Target + Target l_proc = plat_getChipTarget(); + // Default EX Target Init..Not changing it for the time being + Target l_ex((uint64_t)PBA_DEFAULT_EX_CHIPLET_ID); // Determine the access flags - bool l_isPBA = l_req.isPbaFlagSet(); - uint32_t l_isFastMode = l_req.isFastModeSet(); - + // Fast mode flag + bool l_isFastMode = i_hdr.isFastModeSet(); + //LCO Mode for PBA-Put + bool l_isLcoMode = i_hdr.isPbaLcoModeSet(); + if(l_isLcoMode) + { + //Derive the EX target from the input Core Chiplet Id + //Core0/1 -> EX0, Core2/3 -> EX1, Core4/5 -> EX2, Core6/7 -> EX3 + //..so on + l_ex = plat_getTargetHandleByChipletNumber((i_hdr.coreChipletId)/2); + } + // By default, ex_chipletId printed below won't be used unless accompanied + // by LCO_mode. + SBE_DEBUG(SBE_FUNC "FAST_Mode[%d] LCO_Mode[%d] EX_ChipletId[%d]", + l_isFastMode, l_isLcoMode, (i_hdr.coreChipletId)/2); + + // The max granule size for which the ADU/PBA interface if configured uint32_t l_numGranules = 0; - uint64_t l_numCacheLineCompleted = 0; + // Keeps track of number of granules sent to HWP + uint64_t l_granulesCompleted = 0; - // Input Data length in alignment with PBA Cacheline (128 Bytes) - uint64_t l_dataLenCacheLineAligned = l_req.getDataLenPbaCacheAlign(); + // Input Data length in alignment with PBA (128 Bytes) + uint64_t l_lenCacheAligned = i_hdr.getDataLenCacheAlign(); + SBE_DEBUG(SBE_FUNC "Data Aligned Len / Number of data granules = %d", + l_lenCacheAligned); - Target l_proc = - plat_getChipTarget(); - // @TODO via RTC: 128982 - // Accept Ex target from input data - Target l_ex((uint64_t)7); - - while (l_numCacheLineCompleted < l_dataLenCacheLineAligned) + while (l_granulesCompleted < l_lenCacheAligned) { - // If FIFO access failure - if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) + // Call the PBA setup HWP + l_fapiRc = p9_pba_setup( + l_proc, + l_ex, + l_addr, + i_isFlagRead, + ((l_isFastMode) ? (1< l_proc = plat_getChipTarget(); - // Respond with HWP FFDC + // The max granule size for which the ADU/PBA interface if configured + uint32_t l_numGranules = 0; + // Keeps track of number of granules sent to HWP + uint64_t l_granulesCompleted = 0; + + // Input Data length in alignment with PBA (128 Bytes) + uint64_t l_lenCacheAligned = i_hdr.getDataLenCacheAlign(); + SBE_DEBUG(SBE_FUNC "Data Aligned Len / Number of data granules = %d", + l_lenCacheAligned); + + while (l_granulesCompleted < l_lenCacheAligned) + { + // Call the ADU setup HWP + l_fapiRc = p9_adu_setup (l_proc, + l_addr, + i_isFlagRead, + l_aduSetupFlags, + l_numGranules); + // if p9_adu_setup returns error + if( (l_fapiRc != FAPI2_RC_SUCCESS) ) + { + SBE_ERROR(SBE_FUNC" p9_adu_setup Failed"); + // Respond with HWP FFDC l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, SBE_SEC_GENERIC_FAILURE_IN_EXECUTION ); l_ffdc.setRc(l_fapiRc); - break; } + // Assumption is Hwp won't return zero for Num Granules + assert(0 != l_numGranules); - SBE_DEBUG(SBE_FUNC "l_numGranules=[0x%08X]", l_numGranules); - uint64_t l_numAccesses = 0; + SBE_DEBUG(SBE_FUNC "Hwp returned l_numGranules=[0x%08X]",l_numGranules); + uint64_t l_numAcc = 0; - if ((l_numGranules != 0) && - (l_numGranules < - (l_dataLenCacheLineAligned - l_numCacheLineCompleted))) + if (l_numGranules < (l_lenCacheAligned - l_granulesCompleted)) { - l_numAccesses = l_numGranules; + l_numAcc = l_numGranules; } else { - l_numAccesses = - l_dataLenCacheLineAligned - l_numCacheLineCompleted; + l_numAcc = l_lenCacheAligned - l_granulesCompleted; } - uint64_t l_numCurrentAccess = 0; - while (l_numCurrentAccess < l_numAccesses) - { - bool l_lastGranule = false; - bool l_firstGranule = false; - - // @TODO via RTC: 128982 - // ADU support - // Need 8Byte alignment for ADU operations - uint32_t l_dataFifo[32] ; // 128Byte granule for PBA access + // 8Byte granule for ADU access + uint32_t l_dataFifo[MAX_ADU_BUFFER] = {0}; - if (l_numCurrentAccess == (l_numGranules - 1)) + uint64_t l_numCurrAcc = 0; + while (l_numCurrAcc < l_numAcc) + { + bool l_lastGran = (l_numCurrAcc == (l_numAcc-1)) ? true : false; + bool l_firstGran = (l_numCurrAcc == 0) ? true : false; + + // With ECC or ITAG the output length of a granule will become + // 9 bytes instead of 8, To align it we will merge 4 output granule + // before putting it in the Downstream FIFO i.e. 9*4 = 36Bytes + // which is 4Bytes aligned size. + // With Both ECC and ITag, the o/p length of a granule will become + // 10Bytes instead of 8, To align it we will merge 4 output granule + // before putting it in the Downstream FIFO i.e. 10*4 = 40bytes + // So in ADU Read case we will use the same buffer with 10Bytes + // offset to fill the 40bytes. + + // Both Ecc and ITag Present = 40Bytes is the alignment length + /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes + * D[08-Itag] D[09-Ecc] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 6D B + * D[10] D[11] D [12-Itag] D[13-Ecc] D[14] D[15] D[16] D[17] + * D[18] D[19] D[1a] D[1b] D[1c-Itag] D[1d-Ecc] D[1e] D[1f] + * D[20] D[21] D[22] D[23] D[24] D[25] D[26-Itag] D[27-Ecc] + */ + // Only Ecc Present = 36 Bytes is the alignment length + /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes + * D[08-Ecc] D[09] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 7D B + * D[10] D[11-Ecc] D [12] D[13] D[14] D[15] D[16] D[17] + * D[18] D[19] D[1a-Ecc] D[1b] D[1c] D[1d] D[1e] D[1f] + * D[20] D[21] D[22] D[23-Ecc] + */ + // Only ITag Present = 36 Bytes is the alignment length + /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes + * D[08-Itag] D[09] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 7D B + * D[10] D[11-Itag] D [12] D[13] D[14] D[15] D[16] D[17] + * D[18] D[19] D[1a-Itag] D[1b] D[1c] D[1d] D[1e] D[1f] + * D[20] D[21] D[22] D[23-Itag] + */ + uint8_t l_bufIdx = 0; + + // If this is putmem request, read input data from the upstream FIFO + if (!i_isFlagRead) { - l_lastGranule = true; - } + // l_sizeMultiplier * 4B Upstream FIFO = Granule size 128B + uint32_t l_len2dequeue = l_sizeMultiplier; + l_rc = sbeUpFifoDeq_mult (l_len2dequeue, + (uint32_t *)&l_dataFifo, + false); + checkSbeRC(l_rc); - if (l_numCurrentAccess == 0) - { - l_firstGranule = true; + // Insert the ECC if ECC Mode is set + if(l_isEccMode) + { + uint8_t l_eccPos = 8; + if(l_isItagMode) + { + l_eccPos = 9; + } + ((uint8_t*)&l_dataFifo)[l_eccPos] = i_hdr.eccByte; + } } - - // If this is putmem request, - // read input data from the upstream FIFO - if (!i_flagGetOrPut) + else { - // @TODO via RTC: 128982 - // Use a granule variable - l_len2dequeue = 32; - - l_rc = sbeUpFifoDeq_mult (l_len2dequeue, - (uint32_t *)&l_dataFifo, - false); - - // If there was an underlying FIFO operation failure - if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) + //Adu Read Mode - with either ECC or ITag or Both + // Calculate the MODULUS + uint8_t l_mod = (l_numCurrAcc % 4); + if( (l_mod) && ((l_isEccMode) || (l_isItagMode)) ) { - // Let command processor routine to handle the RC. - break; + // Default Init it for 1byte extra + l_bufIdx = (ADU_GRAN_SIZE_BYTES * l_mod) + l_mod; + if((l_isEccMode) && (l_isItagMode)) + { + l_bufIdx = l_bufIdx + l_mod; + } } } - // Call PBA access HWP for PBA write or read request - l_fapiRc = p9_pba_access ( l_proc, l_pbaAddr, - i_flagGetOrPut, - l_isFastMode, - l_firstGranule, - l_lastGranule, - (uint8_t *)&l_dataFifo); - - // if p9_pba_access returns error + // Call ADU access HWP for ADU write/read request + l_fapiRc = p9_adu_access ( + l_proc, + l_addr, + i_isFlagRead, + l_aduSetupFlags, + l_firstGran, + l_lastGran, + &(((uint8_t *)&(l_dataFifo))[l_bufIdx])); + // if p9_adu_access returns error if( l_fapiRc != FAPI2_RC_SUCCESS ) { - SBE_ERROR(SBE_FUNC" p9_pba_access Failed"); - + SBE_ERROR(SBE_FUNC" p9_adu_access Failed"); // Respond with HWP FFDC l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, SBE_SEC_GENERIC_FAILURE_IN_EXECUTION ); l_ffdc.setRc(l_fapiRc); - break; } // If this is a getmem request, // need to push the data into the downstream FIFO - if (i_flagGetOrPut) + if (i_isFlagRead) { - // Break out on underlying FIFO operational error - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) + // Number of 4Bytes to put, to align with Granule Size + uint32_t l_len = l_sizeMultiplier; // l_len*4 = Granule Size + + //Enter the below 'if' if ADU Read Mode with Either Ecc or ITag + //or both set. During non-aligned Transaction (but not the last) + //then set the len as zero so as to skip the unalign byte send, + //during next transaction when the data is aligned it will take + //care of sending all granules. + //If the below condition is not met then for ADU Read Mode will + //happen to write on DownStream FIFO for each granule. + + //Calculate the MODULUS + uint8_t l_mod = (l_numCurrAcc % 4); + if((l_isEccMode) || (l_isItagMode)) { - break; + if( (l_mod == 3) || (l_lastGran) ) + { + l_len = calInterAduLenForUpFifo(l_mod,l_isItagMode, + l_isEccMode); + l_len = align4ByteWordLength(l_len); + } + else + { + // If it is not the last granule or on the 4th entry + // into the data buffer, need not send it to Upstream + // Fifo + l_len = 0; + } } - - uint32_t l_len = 32; - l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo); - - // If FIFO failure - if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) + if(l_len) { - // Let command processor routine to handle the RC. - break; + l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo); + checkSbeRC(l_rc); } } - l_numCacheLineCompleted++; - l_numCurrentAccess++; - + l_granulesCompleted++; + l_numCurrAcc++; } // End inner while loop if ( (l_fapiRc != FAPI2_RC_SUCCESS) || @@ -235,96 +652,95 @@ uint32_t sbeMemAccess_Wrap(const bool i_flagGetOrPut) break; } - // @TODO via RTC: 128982 - // Use a granule variable - l_pbaAddr += 128 * l_numCacheLineCompleted; - - } // End..while (l_numCacheLineCompleted < l_dataLenCacheLineAligned); + l_addr += l_granuleSize * l_granulesCompleted; + } // End..while (l_granulesCompleted < l_lenCacheAligned); // Now build and enqueue response into downstream FIFO do { // If there was a FIFO error, will skip sending the response, // instead give the control back to the command processor thread - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) - { - break; - } - - l_len2dequeue = 0; + checkSbeRC(l_rc); // If there was a HWP failure for putmem request, // need to Flush out upstream FIFO, until EOT arrives - if (!i_flagGetOrPut) + if (!i_isFlagRead) { - if ( l_fapiRc != FAPI2_RC_SUCCESS ) - { - l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, - true, true); - } - // For other success paths, just attempt to offload - // the next entry, which is supposed to be the EOT entry - else - { - l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true); - } - } - - // Break out on underlying FIFO operational error - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) - { - break; + l_rc = flushUpstreamFifo(l_fapiRc); + checkSbeRC(l_rc); } // first enqueue the length of data actually written uint32_t l_len = 1; - uint32_t l_respLen = l_numCacheLineCompleted*8*16; + uint32_t l_respLen = sbeAduLenInUpStreamFifo( + l_granulesCompleted, + l_isItagMode, + l_isEccMode); + + SBE_DEBUG(SBE_FUNC "Total length Pushed for ChipOp [%d]", l_respLen); l_rc = sbeDownFifoEnq_mult ( l_len, &l_respLen ); + checkSbeRC(l_rc); - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) - { - break; - } + l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc); + } while(false); - // Now enqueue the minimum response header - uint32_t l_dist2Hdr = 1; - l_len = sizeof(l_respHdr) / sizeof(uint32_t); - l_rc = sbeDownFifoEnq_mult ( l_len, reinterpret_cast - (&l_respHdr) ); + SBE_EXIT(SBE_FUNC); + return l_rc; + #undef SBE_FUNC +} - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) - { - break; - } +/////////////////////////////////////////////////////////////////////// +// @brief sbeMemAccess_Wrap Memory Access Wrapper function +// +// @param [in] i_isFlagRead Flag to indicate the memory Access Type +// true : GetMem ChipOp +// false : PutMem ChipOp +// +// @return RC from the method +/////////////////////////////////////////////////////////////////////// +uint32_t sbeMemAccess_Wrap(const bool i_isFlagRead) +{ + #define SBE_FUNC " sbeMemAccess_Wrap " + SBE_ENTER(SBE_FUNC); + + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + // Create an instance of Memory Access ChipOp structure + sbeMemAccessReqMsgHdr_t l_req = {0}; - l_dist2Hdr += l_len; + // Offload the common header from the Upstream FIFO + uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t); + l_rc = sbeUpFifoDeq_mult(l_len2dequeue, (uint32_t *)&l_req, i_isFlagRead); - // Enqueue FFDC data if there is one - if( l_ffdc.getRc() ) + if(!l_rc) + { + // Calculate the PBA/ADU address from the given input + uint64_t l_addr = l_req.getAddr(); + SBE_DEBUG(SBE_FUNC "Address Upper[0x%08X] Lower[0x%08X] Flags[0x%08X] " + "Length[0x%08X]", ((l_addr >>32) & 0xFFFFFFFF), + (l_addr & 0xFFFFFFFF), l_req.flags, l_req.len); + + // PBA + bool l_isPBA = l_req.isPbaFlagSet(); + if(l_isPBA) { - l_len = sizeof(l_ffdc) / sizeof(uint32_t); - l_rc = sbeDownFifoEnq_mult ( l_len, - reinterpret_cast(&l_ffdc) ); - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) + l_rc = processPbaRequest(l_req, i_isFlagRead); + if(l_rc) { - break; + SBE_ERROR(SBE_FUNC "processPbaRequest failed"); } - - l_dist2Hdr += l_len; - - // @TODO via 129076: - // Need to add FFDC data as well. } - - l_len = sizeof(l_dist2Hdr) / sizeof(uint32_t); - l_rc = sbeDownFifoEnq_mult ( l_len, &l_dist2Hdr); - - if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL ) + // ADU + else { - break; + l_rc = processAduRequest(l_req, i_isFlagRead); + if(l_rc) + { + SBE_ERROR(SBE_FUNC "processAduRequest failed"); + } } - - } while(false); - + } + // If there was a FIFO error, will skip sending the response, + // instead give the control back to the command processor thread + SBE_EXIT(SBE_FUNC); return l_rc; #undef SBE_FUNC } @@ -333,24 +749,13 @@ uint32_t sbeMemAccess_Wrap(const bool i_flagGetOrPut) ////////////////////////////////////////////////////// uint32_t sbePutMem (uint8_t *i_pArg) { - #define SBE_FUNC " sbePutMem " - SBE_ENTER(SBE_FUNC); - return sbeMemAccess_Wrap (false); - - #undef SBE_FUNC } ///////////////////////////////////////////////////// ////////////////////////////////////////////////////// uint32_t sbeGetMem (uint8_t *i_pArg) { - #define SBE_FUNC " sbeGetMem " - SBE_ENTER(SBE_FUNC); - return sbeMemAccess_Wrap (true); - - #undef SBE_FUNC } - diff --git a/sbe/sbefw/sbecmdmemaccess.H b/sbe/sbefw/sbecmdmemaccess.H index 9fcaf5f0..1b7dddc0 100644 --- a/sbe/sbefw/sbecmdmemaccess.H +++ b/sbe/sbefw/sbecmdmemaccess.H @@ -28,5 +28,4 @@ uint32_t sbeGetMem (uint8_t *i_pArg); */ uint32_t sbePutMem (uint8_t *i_pArg); - #endif /* __SBEFW_SBECMDMEMACCESS_H */ diff --git a/sbe/test/test.xml b/sbe/test/test.xml index 23f0d46f..f63d269c 100755 --- a/sbe/test/test.xml +++ b/sbe/test/test.xml @@ -12,6 +12,7 @@ ../simics/targets/p9_nimbus/sbeTest/testCntlInstruction.xml ../simics/targets/p9_nimbus/sbeTest/testRegAccess.xml ../simics/targets/p9_nimbus/sbeTest/testFifoReset.xml + ../simics/targets/p9_nimbus/sbeTest/testAduMem.xml sbe-trace 0 diff --git a/sbe/test/testAduMem.xml b/sbe/test/testAduMem.xml new file mode 100644 index 00000000..dde43724 --- /dev/null +++ b/sbe/test/testAduMem.xml @@ -0,0 +1,19 @@ + + + + run-python-file targets/p9_nimbus/sbeTest/testAduMem_ecc.py + yes + + + run-python-file targets/p9_nimbus/sbeTest/testAduMem_itag.py + yes + + + run-python-file targets/p9_nimbus/sbeTest/testAduMem_withEccItag.py + yes + + + run-python-file targets/p9_nimbus/sbeTest/testAduMem_noEccNoItag.py + yes + + diff --git a/sbe/test/testAduMem_ecc.py b/sbe/test/testAduMem_ecc.py new file mode 100644 index 00000000..358d9ae9 --- /dev/null +++ b/sbe/test/testAduMem_ecc.py @@ -0,0 +1,45 @@ +import sys +sys.path.append("targets/p9_nimbus/sbeTest" ) +import testUtil +err = False + +LOOP_COUNT = 1 + +GETMEMADU_TESTDATA_ECC = [0,0,0,0x6, + 0,0,0xA4,0x01, + 0,0,0x0,0xAD, #CoreChipletId/EccByte/Flags - CacheInhibit/FastMode/NoTag/Ecc/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x20] # length of data + +GETMEMADU_EXPDATA_ECC = [0x00,0x00,0x00,0x24, # length of data + 0xc0,0xde,0xa4,0x01, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03]; + +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testUtil.runCycles( 10000000 ) + + # GetMemAdu with Ecc + testUtil.writeUsFifo( GETMEMADU_TESTDATA_ECC) + testUtil.writeEot( ) + + testUtil.readDsEntry ( 9 ) + testUtil.readDsFifo( GETMEMADU_EXPDATA_ECC) + testUtil.runCycles( 10000000 ) + testUtil.readEot( ) + +#------------------------------------------------- +# Calling all test code +#------------------------------------------------- +main() + +if err: + print ("\nTest Suite completed with error(s)") + #sys.exit(1) +else: + print ("\nTest Suite completed with no errors") + #sys.exit(0); + diff --git a/sbe/test/testAduMem_itag.py b/sbe/test/testAduMem_itag.py new file mode 100644 index 00000000..33160602 --- /dev/null +++ b/sbe/test/testAduMem_itag.py @@ -0,0 +1,43 @@ +import sys +sys.path.append("targets/p9_nimbus/sbeTest" ) +import testUtil +err = False + +GETMEMADU_TESTDATA_ITAG = [0,0,0,0x6, + 0,0,0xA4,0x01, + 0,0,0x0,0xB5, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/Tag/NoEcc/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x40] # length of data + +GETMEMADU_EXPDATA_ITAG = [0x00,0x00,0x00,0x48, # length of data + 0xc0,0xde,0xa4,0x01, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03]; + +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testUtil.runCycles( 10000000 ) + + # GetMemAdu with Itag + testUtil.writeUsFifo( GETMEMADU_TESTDATA_ITAG ) + testUtil.writeEot( ) + + testUtil.readDsEntry ( 18 ) + testUtil.readDsFifo( GETMEMADU_EXPDATA_ITAG ) + testUtil.runCycles( 10000000 ) + testUtil.readEot( ) + +#------------------------------------------------- +# Calling all test code +#------------------------------------------------- +main() + +if err: + print ("\nTest Suite completed with error(s)") + #sys.exit(1) +else: + print ("\nTest Suite completed with no errors") + #sys.exit(0); + diff --git a/sbe/test/testAduMem_noEccNoItag.py b/sbe/test/testAduMem_noEccNoItag.py new file mode 100644 index 00000000..6f1d3350 --- /dev/null +++ b/sbe/test/testAduMem_noEccNoItag.py @@ -0,0 +1,76 @@ +import sys +sys.path.append("targets/p9_nimbus/sbeTest" ) +import testUtil +err = False + +LOOP_COUNT = 1 + +PUTMEMADU_CNTLDATA = [0,0,0,0, + 0,0,0xA4,0x02, + 0,0,0x0,0xA5, #CoreChipletId/EccByte/Flags -> NoEccOverride/CacheInhibit/FastMode/NoTag/NoEcc/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x10] # length of data + +PUTMEMADU_TESTDATA = [0xab,0xcd,0xef,0x12, + 0xba,0xdc,0xfe,0x21, + 0x34,0x56,0x78,0x9a, + 0x43,0x65,0x87,0xa9] + +PUTMEMADU_EXPDATA = [0x00,0x00,0x00,0x10, # length of data + 0xc0,0xde,0xa4,0x02, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03]; + + + +GETMEMADU_TESTDATA = [0,0,0,0x6, + 0,0,0xA4,0x01, + 0,0,0x0,0xA5, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/NoTag/NoEcc/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x10] # length of data + +GETMEMADU_EXPDATA = [0xab,0xcd,0xef,0x12, #data + 0xba,0xdc,0xfe,0x21, + 0x34,0x56,0x78,0x9a, + 0x43,0x65,0x87,0xa9, + 0x00,0x00,0x00,0x10, # length of data + 0xc0,0xde,0xa4,0x01, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03]; + + +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testUtil.runCycles( 10000000 ) + + #PutMemAdu Test + testUtil.writeUsFifo( PUTMEMADU_CNTLDATA ) + testUtil.writeUsFifo( PUTMEMADU_TESTDATA ) + testUtil.writeEot( ) + + testUtil.readDsFifo( PUTMEMADU_EXPDATA ) + testUtil.readEot( ) + + # GetMemAdu test + testUtil.writeUsFifo( GETMEMADU_TESTDATA ) + testUtil.writeEot( ) + + testUtil.readDsFifo( GETMEMADU_EXPDATA ) + testUtil.runCycles( 10000000 ) + testUtil.readEot( ) + +#------------------------------------------------- +# Calling all test code +#------------------------------------------------- +main() + +if err: + print ("\nTest Suite completed with error(s)") + #sys.exit(1) +else: + print ("\nTest Suite completed with no errors") + #sys.exit(0); + diff --git a/sbe/test/testAduMem_withEccItag.py b/sbe/test/testAduMem_withEccItag.py new file mode 100644 index 00000000..5980a9a4 --- /dev/null +++ b/sbe/test/testAduMem_withEccItag.py @@ -0,0 +1,43 @@ +import sys +sys.path.append("targets/p9_nimbus/sbeTest" ) +import testUtil +err = False + +GETMEMADU_TESTDATA_ECC_ITAG = [0,0,0,0x6, + 0,0,0xA4,0x01, + 0,0,0x0,0xBD, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/Tag/Ecc/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x40] # length of data + +GETMEMADU_EXPDATA_ECC_ITAG = [0x00,0x00,0x00,0x50, # length of data + 0xc0,0xde,0xa4,0x01, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03]; + +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testUtil.runCycles( 10000000 ) + + # GetMemAdu with Ecc with Itag test + testUtil.writeUsFifo( GETMEMADU_TESTDATA_ECC_ITAG ) + testUtil.writeEot( ) + + testUtil.readDsEntry ( 20 ) + testUtil.readDsFifo( GETMEMADU_EXPDATA_ECC_ITAG ) + testUtil.runCycles( 10000000 ) + testUtil.readEot( ) + +#------------------------------------------------- +# Calling all test code +#------------------------------------------------- +main() + +if err: + print ("\nTest Suite completed with error(s)") + #sys.exit(1) +else: + print ("\nTest Suite completed with no errors") + #sys.exit(0); + diff --git a/sbe/test/testAduMem_withEccWithItagReadWrite.py b/sbe/test/testAduMem_withEccWithItagReadWrite.py new file mode 100644 index 00000000..8e2de7a0 --- /dev/null +++ b/sbe/test/testAduMem_withEccWithItagReadWrite.py @@ -0,0 +1,73 @@ +import sys +sys.path.append("targets/p9_nimbus/sbeTest" ) +import testUtil +err = False + +LOOP_COUNT = 1 + +PUTMEMADU_CNTLDATA = [0,0,0,0, + 0,0,0xA4,0x02, + 0,0x07,0x0,0xBD, #CoreChipletId/EccByteTrue/Flags -> EccOverride/CacheInhibit/FastMode/Tag/EccOverride/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x08] # length of data + +PUTMEMADU_TESTDATA = [0xab,0xcd,0xef,0x12, + 0xba,0xdc,0xfe,0x21] + +PUTMEMADU_EXPDATA = [0x00,0x00,0x00,0x0a, # length of data + 0xc0,0xde,0xa4,0x02, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03] + + + +GETMEMADU_TESTDATA = [0,0,0,0x6, + 0,0,0xA4,0x01, + 0,0,0x0,0xBD, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/Tag/Ecc/AutoIncr/Adu/Proc + 0,0,0,0, # Addr Upper 32 bit + 0x08,0x00,0x00,0x00, # Addr Lower 32 bit + 0x00,0x00,0x00,0x08] # length of data + +GETMEMADU_EXPDATA = [0xab,0xcd,0xef,0x12, #data + 0xba,0xdc,0xfe,0x21, + 0x01,0x07,0,0, #First Byte is iTag / Second Byte is ECC + 0x00,0x00,0x00,0x0a, # length of data + 0xc0,0xde,0xa4,0x01, + 0x0,0x0,0x0,0x0, + 0x00,0x0,0x0,0x03]; + + +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testUtil.runCycles( 10000000 ) + + #PutMemAdu Test + testUtil.writeUsFifo( PUTMEMADU_CNTLDATA ) + testUtil.writeUsFifo( PUTMEMADU_TESTDATA ) + testUtil.writeEot( ) + + testUtil.readDsFifo( PUTMEMADU_EXPDATA ) + testUtil.readEot( ) + + # GetMemAdu test + testUtil.writeUsFifo( GETMEMADU_TESTDATA ) + testUtil.writeEot( ) + + testUtil.readDsFifo( GETMEMADU_EXPDATA ) + testUtil.runCycles( 10000000 ) + testUtil.readEot( ) + +#------------------------------------------------- +# Calling all test code +#------------------------------------------------- +main() + +if err: + print ("\nTest Suite completed with error(s)") + #sys.exit(1) +else: + print ("\nTest Suite completed with no errors") + #sys.exit(0); + -- cgit v1.2.1