From a697687b5e5e15b00b841db5f2c8c66ee9d8ef35 Mon Sep 17 00:00:00 2001 From: Glenn Miles Date: Thu, 6 Jun 2019 23:57:56 -0500 Subject: [PATCH] Add MMIO test cases that force failures Change-Id: I9af1230917c1629c9f9568ae6645291c11b0140e Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/78524 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Matt Derksen Reviewed-by: Roland Veloz Reviewed-by: Daniel M. Crowell --- src/build/simics/standalone.simics | 8 ++ src/usr/mmio/test/makefile | 2 +- src/usr/mmio/test/mmiotest.H | 167 ++++++++++++++++++++++++----- 3 files changed, 147 insertions(+), 30 deletions(-) diff --git a/src/build/simics/standalone.simics b/src/build/simics/standalone.simics index 5e589ba177a..0548c1b0e5c 100755 --- a/src/build/simics/standalone.simics +++ b/src/build/simics/standalone.simics @@ -143,6 +143,14 @@ if ($hb_mode == 0) { #Only do this on Axone and later models that have Explorer $obj->mscc_regs_xcbi_ram1[14] = 0x063EF2EE $obj->mscc_regs_xcbi_ram1[15] = 0x063B5957 $obj->mscc_regs_xcbi_ram1[16] = 0x40A3A12D + + # Allow for testing MMIO HW failures + # Forces write access to TRACE_TRDATA_CONFIG_0 to fail + # in src/usr/mmio/test/mmiotest.H + # NOTE: address is left shifted 3 and has MMIO + # offset (0x100000000) added. + $obj->mmio_regs_mmioerr = 0x0000000140082018 + } } diff --git a/src/usr/mmio/test/makefile b/src/usr/mmio/test/makefile index bb5ffe21dfd..68c11b6048d 100644 --- a/src/usr/mmio/test/makefile +++ b/src/usr/mmio/test/makefile @@ -27,7 +27,7 @@ ROOTPATH = ../../../.. MODULE = testmmio EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/ - +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/ TESTS = *.H diff --git a/src/usr/mmio/test/mmiotest.H b/src/usr/mmio/test/mmiotest.H index 034e2f0523f..7d2422b986e 100644 --- a/src/usr/mmio/test/mmiotest.H +++ b/src/usr/mmio/test/mmiotest.H @@ -31,79 +31,188 @@ #include #include #include +#include +#include + +#define SCOM2MMIO_ADDR(_ADDR) (EXPLR_IB_MMIO_OFFSET | (_ADDR << 3)) +#define CNFG2MMIO_ADDR(_ADDR) (EXPLR_IB_CONFIG_OFFSET | _ADDR) +#define BYTESWAP64(_DATA) (__builtin_bswap64(_DATA)) static const uint64_t EXPLR_IB_CONFIG_OFFSET = 0x0000000000000000ull; static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB +// NOTE: changing this address requires changes +// to src/build/simics/standalone.simics +static const uint64_t EXPLR_INVALID_SCOM_ADDR = + EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_0; + + class MmioTest : public CxxTest::TestSuite { public: /** - * @brief Test valid MMIO calls + * @brief Test MMIO calls */ - void test_Valid(void) + void testExplrMMIO(void) { - TS_TRACE("MmioTest::test_Valid> Start" ); + TS_INFO("testExplrMMIO> Start" ); - uint64_t fails = 0; - uint64_t total = 0; errlHndl_t l_err = nullptr; uint32_t regdata4 = 0; size_t op_size = 0; + uint64_t l_buffer64; // Get OCMB target, return if there is no OCMB - TARGETING::TargetHandle_t ocmb_target = nullptr; + TARGETING::TargetHandle_t explr_target = nullptr; TARGETING::TargetHandleList ocmb_target_list; TARGETING::getAllChips(ocmb_target_list, TARGETING::TYPE_OCMB_CHIP); if (ocmb_target_list.size() == 0) { - TS_TRACE("MmioTest::test_Valid> Target is NULL"); - TS_INFO("MmioTest::test_Valid> Target is NULL"); + TS_INFO("testExplrMMIO> No OCMB targets found. Exiting."); + return; + } + explr_target = ocmb_target_list[0]; + if(explr_target->getAttr() != + POWER_CHIPID::EXPLORER_16) + { + TS_INFO("testExplrMMIO> No explorer targets found. Exiting."); return; } - ocmb_target = ocmb_target_list[0]; // valid read from config space register - ++total; op_size = sizeof(regdata4); l_err = DeviceFW::deviceRead( - ocmb_target, + explr_target, ®data4, op_size, - DEVICE_MMIO_ADDRESS((EXPLR_IB_CONFIG_OFFSET | - EXPLR_OC_O0MBIT_O0DID_LSB), - op_size)); + DEVICE_MMIO_ADDRESS( + CNFG2MMIO_ADDR(EXPLR_OC_O0MBIT_O0DID_LSB), + op_size)); if(l_err != nullptr) { - TS_TRACE("MmioTest::test_Valid> Error for read, RC=0x%04X", - ERRL_GETRC_SAFE(l_err)); - TS_FAIL("MmioTest::test_Valid> Error for read, RC=0x%04X", - ERRL_GETRC_SAFE(l_err)); - ++fails; errlCommit(l_err, CXXTEST_COMP_ID); + TS_FAIL("testExplrMMIO> Error for config read, RC=0x%04X", + ERRL_GETRC_SAFE(l_err)); } // valid write to config space register - ++total; op_size = sizeof(regdata4); l_err = DeviceFW::deviceWrite( - ocmb_target, + explr_target, ®data4, op_size, - DEVICE_MMIO_ADDRESS((EXPLR_IB_CONFIG_OFFSET | - EXPLR_OC_O0CCD_LSB), - op_size)); + DEVICE_MMIO_ADDRESS( + CNFG2MMIO_ADDR(EXPLR_OC_O0CCD_LSB), + op_size)); + if(l_err != nullptr) + { + errlCommit(l_err, CXXTEST_COMP_ID); + TS_FAIL("testExplrMMIO> Error for config write, RC=0x%04X", + ERRL_GETRC_SAFE(l_err)); + } + + // 1st valid write to SCOM register (also sets up + // tests for forcing HW read/write failures) + // Set the PCB error bits (8:10) to binary 100, which means + // 'invalid address' + // NOTE: must byteswap to little endian before writing + uint64_t GIF2PCB_INVALID_SCOM_ADDR_ERROR = 0x0080000000000000ull; + l_buffer64 = BYTESWAP64(GIF2PCB_INVALID_SCOM_ADDR_ERROR); + op_size = sizeof(l_buffer64); + l_err = DeviceFW::deviceWrite( + explr_target, + &l_buffer64, + op_size, + DEVICE_MMIO_ADDRESS( + SCOM2MMIO_ADDR( + EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG), + op_size)); + if(l_err != nullptr) + { + errlCommit(l_err, CXXTEST_COMP_ID); + TS_FAIL("testExplrMMIO> Error for gif2pcb write, RC=0x%04X", + ERRL_GETRC_SAFE(l_err)); + return; + } + + // 2nd valid write to SCOM register (also sets up + // tests for forcing HW read/write failures) + // This register should contain a copy of the GIF2PCB error register + // starting at bit 32 + // NOTE: must byteswap to little endian before writing data + uint64_t PIB2GIF_INVALID_SCOM_ADDR_ERROR = + 0x0000000000000000ull | + ((GIF2PCB_INVALID_SCOM_ADDR_ERROR & + 0xffffc00000000000ull) >> 32); + l_buffer64 = BYTESWAP64(PIB2GIF_INVALID_SCOM_ADDR_ERROR); + op_size = sizeof(l_buffer64); + l_err = DeviceFW::deviceWrite( + explr_target, + &l_buffer64, + op_size, + DEVICE_MMIO_ADDRESS( + SCOM2MMIO_ADDR( + EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG), + op_size)); + if(l_err != nullptr) { - TS_TRACE("MmioTest::test_Valid> Error for write, RC=0x%04X", - ERRL_GETRC_SAFE(l_err)); - TS_FAIL("MmioTest::test_Valid> Error for write, RC=0x%04X", + errlCommit(l_err, CXXTEST_COMP_ID); + TS_FAIL("testExplrMMIO> Error for pib2gif write, RC=0x%04X", ERRL_GETRC_SAFE(l_err)); - ++fails; + return; + } + + // Write to an "invalid" scom address. Should + // return with failure (now that we've set up the error regs). + // NOTE: Also, writing MMIO_OCMB_UE_DETECTED to this register + // sets up the following read to the same register + // to fail. + l_buffer64 = MMIO_OCMB_UE_DETECTED; + op_size = sizeof(l_buffer64); + l_err = DeviceFW::deviceWrite( + explr_target, + &l_buffer64, + op_size, + DEVICE_MMIO_ADDRESS( + SCOM2MMIO_ADDR(EXPLR_INVALID_SCOM_ADDR), + op_size)); + + if(l_err == nullptr) + { + TS_FAIL("testExplrMMIO> " + "did not recieve expected failure on mmio write"); + return; + } + else + { + TS_INFO("testExplrMMIO> recieved expected failure on mmio write"); errlCommit(l_err, CXXTEST_COMP_ID); } - TS_TRACE("Mmio::test_Valid> %d/%d fails", fails, total); + // Read from an "invalid" scom address. Should + // return with failure (now that we've se up the error regs). + op_size = sizeof(l_buffer64); + l_err = DeviceFW::deviceRead( + explr_target, + &l_buffer64, + op_size, + DEVICE_MMIO_ADDRESS( + SCOM2MMIO_ADDR(EXPLR_INVALID_SCOM_ADDR), + op_size)); + if(l_err == nullptr) + { + TS_INFO("testExplrMMIO> data read from invalid address: 0x%016llx", + l_buffer64); + TS_FAIL("testExplrMMIO> " + "did not recieve expected failure on mmio read"); + } + else + { + TS_INFO("testExplrMMIO> recieved expected failure on mmio read"); + errlCommit(l_err, CXXTEST_COMP_ID); + } + TS_INFO("testExplrMMIO> Done"); }; };