diff options
Diffstat (limited to 'src/usr/mmio/test')
-rw-r--r-- | src/usr/mmio/test/makefile | 7 | ||||
-rw-r--r-- | src/usr/mmio/test/mmiotest.H | 277 |
2 files changed, 222 insertions, 62 deletions
diff --git a/src/usr/mmio/test/makefile b/src/usr/mmio/test/makefile index 133f3ca44..3a9af5d71 100644 --- a/src/usr/mmio/test/makefile +++ b/src/usr/mmio/test/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2011,2018 +# Contributors Listed Below - COPYRIGHT 2011,2019 # [+] International Business Machines Corp. # # @@ -25,6 +25,11 @@ ROOTPATH = ../../../.. MODULE = testmmio + +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/ +EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/ + TESTS = *.H diff --git a/src/usr/mmio/test/mmiotest.H b/src/usr/mmio/test/mmiotest.H index f7abd7816..984e94925 100644 --- a/src/usr/mmio/test/mmiotest.H +++ b/src/usr/mmio/test/mmiotest.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* Contributors Listed Below - COPYRIGHT 2011,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -27,83 +27,238 @@ #include <errl/errlentry.H> #include <limits.h> #include <devicefw/driverif.H> -#include <mmio/mmio.H> +#include "../mmio.H" +#include <targeting/common/utilFilter.H> +#include <explorer_scom_addresses.H> +#include <exp_oc_regs.H> +#include <sys/mmio.h> +#include <utils/chipids.H> +#include <test/exptest_utils.H> -extern trace_desc_t* g_trac_mmio; +#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; + +using namespace TARGETING; class MmioTest : public CxxTest::TestSuite { public: /** - * @brief Test valid MMIO calls + * @brief Test MMIO calls */ - void test_Valid(void) + void testExplrMMIO(void) { - TRACFCOMP( g_trac_mmio, "MmioTest::test_Valid> Start" ); + TS_INFO("testExplrMMIO> Start" ); - uint64_t fails = 0; - uint64_t total = 0; errlHndl_t l_err = nullptr; - uint64_t regdata = 0; - size_t op_size = sizeof(uint64_t); - -// TODO RTC 202533 - enable this test once the Axone model is IPLing -// successfully in Simics. -#if 0 - // Get OCMB target, return if there is no OCMB - TARGETING::TargetHandle_t ocmb_target = nullptr; - TARGETING::TargetHandleList ocmb_target_list; - getAllChips(ocmb_target_list, TARGETING::TYPE_OCMB_CHIP); - if (ocmb_target_list.size() == 0) + uint32_t regdata4 = 0; + size_t op_size = 0; + uint64_t l_buffer64; + + // Needed since the device operations could be using inband communication in error path + HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR l_mutex = exptest::getTestMutex(); + if (l_mutex == nullptr) { - TRACFCOMP(g_trac_fsiscom, "MmioTest::test_Valid> Target is NULL"); - TS_INFO("MmioTest::test_Valid> Target is NULL"); + TS_FAIL("testExplrMMIO: unable to get test mutex"); return; } - ocmb_target = ocmb_target_list[0]; - - // read - ++total; - l_err = MMIO::mmioPerformOp( - DeviceFW::READ, - ocmb_target, - ®data, - op_size, - 0x0, - op_size); - if(l_err != nullptr) - { - TRACFCOMP(g_trac_mmio, - "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, MMIO_COMP_ID); - } - // write - ++total; - l_err = MMIO::mmioPerformOp( - DeviceFW::WRITE, - ocmb_target, - ®data, - op_size, - 0x08, - op_size); - if(l_err != nullptr) + // >> atomic section + mutex_lock(l_mutex); + + TargetHandle_t explr_target = nullptr; + + do { + + // Get OCMB target, return if there is no OCMB + TargetHandleList ocmb_target_list; + getAllChips(ocmb_target_list, TYPE_OCMB_CHIP); + if (ocmb_target_list.size() == 0) + { + TS_INFO("testExplrMMIO> No OCMB targets found. Exiting."); + break; + } + explr_target = ocmb_target_list[0]; + if(explr_target->getAttr<ATTR_CHIP_ID>() != + POWER_CHIPID::EXPLORER_16) + { + TS_INFO("testExplrMMIO> No explorer targets found. Exiting."); + break; + } + + // Make sure we're using MMIO to this explorer chip + exptest::enableInbandScomsOcmb(explr_target); + + // valid read from config space register + op_size = sizeof(regdata4); + l_err = DeviceFW::deviceRead( + explr_target, + ®data4, + op_size, + DEVICE_MMIO_ADDRESS( + CNFG2MMIO_ADDR(EXPLR_OC_O0MBIT_O0DID_LSB), + op_size)); + + if(l_err != nullptr) + { + 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 + op_size = sizeof(regdata4); + l_err = DeviceFW::deviceWrite( + explr_target, + ®data4, + 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)); + break; + } + + // 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) + { + errlCommit(l_err, CXXTEST_COMP_ID); + TS_FAIL("testExplrMMIO> Error for pib2gif write, RC=0x%04X", + ERRL_GETRC_SAFE(l_err)); + break; + } + + // 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) + { + ScomSwitches l_switches = + explr_target->getAttr<ATTR_SCOM_SWITCHES>(); + TS_INFO("testExplrMMIO: Current SCOM mode: %s", + (l_switches.useInbandScom)? "MMIO": "I2C"); + TS_FAIL("testExplrMMIO> " + "did not recieve expected failure on mmio write"); + break; + } + else + { + TS_INFO("testExplrMMIO> " + "received expected failure on mmio write"); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + // Re-enable inband scoms after failure disables it + exptest::enableInbandScomsOcmb(explr_target); + + // Read from an "invalid" scom address. Should + // return with failure (now that we've set 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) + { + ScomSwitches l_switches = + explr_target->getAttr<ATTR_SCOM_SWITCHES>(); + TS_INFO("testExplrMMIO> " + "data read from invalid address: 0x%016llx", + l_buffer64); + TS_INFO("testExplrMMIO: Current SCOM mode: %s", + (l_switches.useInbandScom)? "MMIO": "I2C"); + TS_FAIL("testExplrMMIO> " + "did not recieve expected failure on mmio read"); + } + else + { + TS_INFO("testExplrMMIO> " + "received expected failure on mmio read"); + errlCommit(l_err, CXXTEST_COMP_ID); + } + + } while (0); + + // Re-enable inband scoms after failure disables it + if(explr_target != nullptr) { - TRACFCOMP(g_trac_mmio, - "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", - ERRL_GETRC_SAFE(l_err)); - ++fails; - errlCommit(l_err, MMIO_COMP_ID); + exptest::enableInbandScomsOcmb(explr_target); } -#endif - TRACFCOMP(g_trac_mmio, "Mmio::test_Valid> %d/%d fails", fails, total); + // << atomic section + mutex_unlock(l_mutex); + TS_INFO("testExplrMMIO> Done"); }; }; |