From 65667a20e1eaca6af616af02165f0bebb85da2fa Mon Sep 17 00:00:00 2001 From: spashabk-in Date: Tue, 7 Mar 2017 04:50:53 -0600 Subject: ADU 1/2/4B read/write Change-Id: I7deff3bc60639d5ed9d276d0ff962846a4da8f7b Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37582 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: RAJA DAS Reviewed-by: Sachin Gupta --- src/sbefw/sbeSpMsg.H | 4 +- src/sbefw/sbecmdmemaccess.C | 37 +++++++++++--- src/test/testcases/testAduMem.xml | 6 ++- src/test/testcases/testAduMem_124B.py | 95 +++++++++++++++++++++++++++++++++++ src/test/testcases/testMemUtil.py | 13 +++-- 5 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 src/test/testcases/testAduMem_124B.py diff --git a/src/sbefw/sbeSpMsg.H b/src/sbefw/sbeSpMsg.H index 341a9122..0e695dd5 100644 --- a/src/sbefw/sbeSpMsg.H +++ b/src/sbefw/sbeSpMsg.H @@ -464,7 +464,9 @@ typedef struct */ uint64_t getDataLenCacheAlign() const { - uint64_t l_len = (len / 8); + // Expected length in bytes is 1, 2, 4, or multiples of 8, + // won't work for any other values + uint64_t l_len = (len < 8) ? (1) : (len / 8); if(flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA) { l_len = (l_len / 16); diff --git a/src/sbefw/sbecmdmemaccess.C b/src/sbefw/sbecmdmemaccess.C index 6830e73a..87ed5908 100644 --- a/src/sbefw/sbecmdmemaccess.C +++ b/src/sbefw/sbecmdmemaccess.C @@ -118,16 +118,18 @@ inline uint32_t calInterAduLenForUpFifo(uint8_t i_mod, bool i_itag, bool i_ecc) // Calculate the Final Size which is write/read to/from HWP // // @param [in] i_numGranules, Number of granules read/write +// @param [in] i_granuleSize // @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, + uint32_t i_granuleSize, bool i_itag, bool i_ecc) { - uint32_t l_respLen = i_numGranules * ADU_GRAN_SIZE_BYTES; + uint32_t l_respLen = i_numGranules * i_granuleSize; if(i_itag) { // Add one byte for Itag for Each Granule Completed @@ -396,9 +398,15 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, uint32_t l_granuleSize = ADU_GRAN_SIZE_BYTES; p9_ADU_oper_flag l_aduFlag; + l_aduFlag.setTransactionSize(p9_ADU_oper_flag::TSIZE_8); + if(i_hdr.len < 8) + { + l_sizeMultiplier = 1; + l_granuleSize = i_hdr.len; + l_aduFlag.setTransactionSize((p9_ADU_oper_flag::Transaction_size_t)(i_hdr.len)); + } //Default Operation Type is DMA_PARTIAL l_aduFlag.setOperationType(p9_ADU_oper_flag::DMA_PARTIAL); - l_aduFlag.setTransactionSize(p9_ADU_oper_flag::TSIZE_8); l_aduFlag.setLockControl(false); l_aduFlag.setOperFailCleanup(true); l_aduFlag.setNumLockAttempts(SBE_ADU_LOCK_TRIES); @@ -409,6 +417,7 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, { l_aduFlag.setFastMode(true); } + // TODO set DMA_PARTIAL mode by default if CI mode is not set if(i_hdr.isCacheInhibitModeFlagSet()) { l_aduFlag.setOperationType(p9_ADU_oper_flag::CACHE_INHIBIT); @@ -453,11 +462,12 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, // 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); + SBE_DEBUG(SBE_FUNC "User length [%d], Data Aligned Len / " + "Number of data granules = %d", + i_hdr.len, l_lenCacheAligned); // 8Byte granule for ADU access - uint32_t l_dataFifo[MAX_ADU_BUFFER] = {0}; + uint64_t l_dataFifo[MAX_ADU_BUFFER/2] = {0}; while (l_granulesCompleted < l_lenCacheAligned) { @@ -542,6 +552,11 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, (uint32_t *)&l_dataFifo, false); CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); + SBE_DEBUG("l_dataFifo#1 0x%08x%08x", SBE::higher32BWord(l_dataFifo[0]), + SBE::lower32BWord(l_dataFifo[0])); + l_dataFifo[0] >>= (l_addr & 0x07) * 8; + SBE_DEBUG("l_dataFifo#2 0x%08x%08x", SBE::higher32BWord(l_dataFifo[0]), + SBE::lower32BWord(l_dataFifo[0])); // Insert the ECC if ECC Mode is set if(l_isEccMode) @@ -590,7 +605,6 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, l_ffdc.setRc(l_fapiRc); break; } - l_addr += l_granuleSize; // If this is a getmem request, // need to push the data into the downstream FIFO @@ -607,10 +621,10 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, //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_granulesCompleted % 4); if((l_isEccMode) || (l_isItagMode)) { + //Calculate the MODULUS + uint8_t l_mod = (l_granulesCompleted % 4); if( (l_mod == 3) || ((l_granulesCompleted+1) == l_lenCacheAligned) ) { l_len = calInterAduLenForUpFifo(l_mod,l_isItagMode, @@ -627,10 +641,16 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, } if(l_len) { + SBE_DEBUG("l_dataFifo#3 0x%08x%08x", SBE::higher32BWord(l_dataFifo[0]), + SBE::lower32BWord(l_dataFifo[0])); + l_dataFifo[0] <<= (l_addr & 0x07) * 8; + SBE_DEBUG("l_dataFifo#4 0x%08x%08x", SBE::higher32BWord(l_dataFifo[0]), + SBE::lower32BWord(l_dataFifo[0])); l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo); CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); } } + l_addr += l_granuleSize; l_granulesCompleted++; l_numCurrAcc++; } // End inner while loop @@ -661,6 +681,7 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, uint32_t l_len = 1; uint32_t l_respLen = sbeAduLenInUpStreamFifo( l_granulesCompleted, + l_granuleSize, l_isItagMode, l_isEccMode); diff --git a/src/test/testcases/testAduMem.xml b/src/test/testcases/testAduMem.xml index 51d2c2b2..2e38530c 100644 --- a/src/test/testcases/testAduMem.xml +++ b/src/test/testcases/testAduMem.xml @@ -5,7 +5,7 @@ - + @@ -40,4 +40,8 @@ run-python-file targets/p9_nimbus/sbeTest/testAduMem_noEccNoItag.py yes + + run-python-file targets/p9_nimbus/sbeTest/testAduMem_124B.py + yes + diff --git a/src/test/testcases/testAduMem_124B.py b/src/test/testcases/testAduMem_124B.py new file mode 100644 index 00000000..100f7bb4 --- /dev/null +++ b/src/test/testcases/testAduMem_124B.py @@ -0,0 +1,95 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/test/testcases/testAduMem_124B.py $ +# +# OpenPOWER sbe Project +# +# Contributors Listed Below - COPYRIGHT 2017 +# +# +# 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 testUtil +import testMemUtil as testMemProcUtil +err = False + + + +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testUtil.runCycles( 10000000 ) + +# Test case 1: 1byte access + #PutMemAdu Test + data = os.urandom(1) + data = [ord(c) for c in data] + testMemProcUtil.putmem(0x08000000, data, 0xA5) + + # GetMemAdu test + readData = testMemProcUtil.getmem(0x08000000, 1, 0xA5) + if(data == readData): + print ("Success - Write-Read ADU") + else: + print data + print readData + raise Exception('data mistmach') + +# Test case 2: 2byte access + #PutMemAdu Test + data = os.urandom(2) + data = [ord(c) for c in data] + testMemProcUtil.putmem(0x08000000, data, 0xA5) + + # GetMemAdu test + readData = testMemProcUtil.getmem(0x08000000, 2, 0xA5) + if(data == readData): + print ("Success - Write-Read ADU") + else: + print data + print readData + raise Exception('data mistmach') + +# Test case 3: 4byte access + #PutMemAdu Test + data = os.urandom(4) + data = [ord(c) for c in data] + testMemProcUtil.putmem(0x08000000, data, 0xA5) + + # GetMemAdu test + readData = testMemProcUtil.getmem(0x08000000, 4, 0xA5) + if(data == readData): + print ("Success - Write-Read ADU") + else: + print data + print readData + raise Exception('data mistmach') + +#------------------------------------------------- +# 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/src/test/testcases/testMemUtil.py b/src/test/testcases/testMemUtil.py index 95ed304b..30bb94bd 100644 --- a/src/test/testcases/testMemUtil.py +++ b/src/test/testcases/testMemUtil.py @@ -6,6 +6,7 @@ # OpenPOWER sbe Project # # Contributors Listed Below - COPYRIGHT 2017 +# [+] International Business Machines Corp. # # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -56,6 +57,9 @@ def addItagEcc(arr, itag, ecc, eccVal=0): return arrs def putmem(addr, data, flags, ecc=0): + lenInBytes = len(data) + if(len(data) < 8): + data = data+[0]*(4-len(data)) totalLen = 5 + len(data)/4 req = (getsingleword(totalLen) +[ 0,0,0xA4,0x02] @@ -63,17 +67,16 @@ def putmem(addr, data, flags, ecc=0): +gethalfword(flags) #0,0,0x0,0xA5] #CoreChipletId/EccByte/Flags -> NoEccOverride/CacheInhibit/FastMode/NoTag/NoEcc/AutoIncr/Adu/Proc + getdoubleword(addr) - + getsingleword(len(data)) # length of data + + getsingleword(lenInBytes) # length of data + data) testUtil.writeUsFifo(req) testUtil.writeEot( ) testUtil.runCycles( 10000000 ) - lenWritten = len(data) if(flags & 0x0008): - lenWritten += int(len(data)/8) + lenInBytes += int(len(data)/8) if(flags & 0x0010): - lenWritten += int(len(data)/8) - expData = (getsingleword(lenWritten) + lenInBytes += int(len(data)/8) + expData = (getsingleword(lenInBytes) +[0xc0,0xde,0xa4,0x02, 0x0,0x0,0x0,0x0, 0x00,0x0,0x0,0x03]) -- cgit v1.2.1