diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/usr/devicefw/userif.H | 47 | ||||
| -rw-r--r-- | src/usr/scom/runtime/test/makefile | 6 | ||||
| -rw-r--r-- | src/usr/scom/runtime/test/testscom_rt.H | 115 | ||||
| -rw-r--r-- | src/usr/scom/scom.mk | 2 | ||||
| -rw-r--r-- | src/usr/scom/scomtrans.C | 24 | ||||
| -rw-r--r-- | src/usr/scom/scomtrans.H | 8 | ||||
| -rw-r--r-- | src/usr/scom/test/scomtest.H | 3 |
7 files changed, 154 insertions, 51 deletions
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H index 06195f326..970a747a6 100644 --- a/src/include/usr/devicefw/userif.H +++ b/src/include/usr/devicefw/userif.H @@ -71,14 +71,51 @@ namespace DeviceFW }; #ifndef PARSER + + /** Single argument version of the macro to provide the correct information + * to perform a scomRead or scomWrite. Takes in a scom address + * + * @param[in] i_address - scom address that you are writing to or reading from + */ + #define DEVICE_SCOM_ADDRESS_1_ARGS(i_address)\ + DeviceFW::SCOM, static_cast<uint64_t>((i_address)), static_cast<uint64_t>(0) + + /** 2 argument version of the macro to provide the correct information to + * preform a scomRead or scomWrite. Takes in a scom address and an opmode + * + * @param[in] i_address - scom addr that you are writing to or reading from + * @param[in] i_opMode - fapi2 opMode used by HWPs to conduct scoms in a + * certain way + */ + #define DEVICE_SCOM_ADDRESS_2_ARGS(i_address, i_opMode)\ + DeviceFW::SCOM, static_cast<uint64_t>((i_address)), static_cast<uint64_t>(i_opMode) + + /** This is the trick to figuring out if the second argument is there or not + * by using this in conjunction with __VA_ARGS__ , which has variable length + * you can select the appropriate macro for the number of arguments present + * + * @param[in] arg1 - __VA_ARGS__ that you are trying to determine size of + * @param[in] arg2 - 2 argument version of macro + * @param[in] arg1 - 1 argument version of macro + */ + #define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 + + /** This is the implementation GET_3RD_ARG macro that selects either + * the 1 argument macro for scom address that only takes an addressing + * or else use the 2 arg macro that takes in an address as well as an opmode + * + * @param[in] _VA_ARGS__ - __VA_ARGS__ that you are trying to determine size of + */ + #define DEVICE_SCOM_ADDRESS_MACRO_CHOOSER(...) \ + GET_3RD_ARG(__VA_ARGS__, DEVICE_SCOM_ADDRESS_2_ARGS, DEVICE_SCOM_ADDRESS_1_ARGS ) + /** Construct the device addressing parameters for SCOM device ops. - * @param[in] i_address - Scom address to operate on. - */ - #define DEVICE_SCOM_ADDRESS(i_address) \ - DeviceFW::SCOM, static_cast<uint64_t>((i_address)) + * @param[in] i_address - Scom address to operate on. + */ + #define DEVICE_SCOM_ADDRESS(...) DEVICE_SCOM_ADDRESS_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) /** Construct the device addressing parameters for the PRESENT device ops. - */ + */ #define DEVICE_PRESENT_ADDRESS() \ DeviceFW::PRESENT diff --git a/src/usr/scom/runtime/test/makefile b/src/usr/scom/runtime/test/makefile index a45467457..6a8470f35 100644 --- a/src/usr/scom/runtime/test/makefile +++ b/src/usr/scom/runtime/test/makefile @@ -5,7 +5,9 @@ # # OpenPOWER HostBoot Project # -# COPYRIGHT International Business Machines Corp. 2013,2014 +# Contributors Listed Below - COPYRIGHT 2013,2016 +# [+] 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. @@ -23,6 +25,8 @@ HOSTBOOT_RUNTIME = 1 ROOTPATH = ../../../../.. +EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/ + MODULE = testscom_rt TESTS = *.H diff --git a/src/usr/scom/runtime/test/testscom_rt.H b/src/usr/scom/runtime/test/testscom_rt.H index 18d529fc2..fbb15548f 100644 --- a/src/usr/scom/runtime/test/testscom_rt.H +++ b/src/usr/scom/runtime/test/testscom_rt.H @@ -37,7 +37,7 @@ #include <devicefw/userif.H> #include <fsi/fsiif.H> #include <targeting/common/util.H> - +#include <hw_access_def.H> #include <devicefw/driverif.H> @@ -352,12 +352,18 @@ public: } +// Currently this test can only be verified manually by looking at the traces +// There is no way to tell if the requested deviceRead/deviceWrite followed the +// opMode. For example you cannot know if the core skipped the wakeup when the +// DO_NOT_DO_WAKEUP opMode is set unless you look at the traces to see if there +// is traces from the wakeup code path. In the future when the wakeup is +// implemented we may have the ability to know if a core has tried to wake or not. +// @TODO RTC: 132413 - - void test_TranslateScom_EX(void) + void test_opModes(void) { - TRACFCOMP( g_trac_scom, "ScomTest::test_TranslateScom> Start" ); + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes> Start" ); uint64_t fails = 0; uint64_t total = 0; @@ -383,6 +389,7 @@ public: epath.addLast(TARGETING::TYPE_SYS,0); epath.addLast(TARGETING::TYPE_NODE,0); epath.addLast(TARGETING::TYPE_PROC,0); + epath.addLast(TARGETING::TYPE_EQ,0); scom_targets[myProc0] = TARGETING::targetService().toTarget(epath); @@ -393,9 +400,13 @@ public: epath.addLast(TARGETING::TYPE_EX,1); scom_targets[myEX1] = TARGETING::targetService().toTarget(epath); - // remote EX1 target (off of sys-0/node-0/proc-0/EX1) + // remove EX1 target (off of sys-0/node-0/proc-0/eq-0/EX1) + epath.removeLast(); + // remove eq0 target (off of sys-0/node-0/proc-0/eq-0) epath.removeLast(); + // add eq2 target. + epath.addLast(TARGETING::TYPE_EQ,2); // add EX5 target. epath.addLast(TARGETING::TYPE_EX,5); scom_targets[myEX5] = TARGETING::targetService().toTarget(epath); @@ -406,11 +417,21 @@ public: TARGETING::Target* target; uint64_t addr; uint64_t data; + fapi2::OpModes mode; + bool expectErr; } test_data[] = { - { scom_targets[myEX1], 0x10040000 ,0x7676767676767676}, - { scom_targets[myEX5], 0x10040002, 0x9191919191919191}, - { scom_targets[myEX5], 0x13040002, 0xabcdabcdabcdabcd}, // invalid unit 0 address - { scom_targets[myEX1], 0x000F0166, 0xabcdabcdabcdabcd}, // invalid address range for target + { scom_targets[myEX1], 0x21000000 ,0x7676767676767676, fapi2::NORMAL, false}, // pervasive addr does not req wakeup + { scom_targets[myEX5], 0x20010A02, 0x9191919191919191, fapi2::NORMAL, false}, + { scom_targets[myEX5], 0x13040002, 0xabcdabcdabcdabcd, fapi2::NORMAL, true}, // invalid unit 0 address + { scom_targets[myEX1], 0x000F0166, 0xabcdabcdabcdabcd, fapi2::NORMAL, true}, // invalid address range for target + { scom_targets[myEX1], 0x21000000 ,0x7676767676767676, fapi2::IGNORE_HW_ERROR, false}, // pervasive addr does not req wakeup + { scom_targets[myEX5], 0x20010A02, 0x9191919191919191, fapi2::IGNORE_HW_ERROR, false}, + { scom_targets[myEX5], 0x13040002, 0xabcdabcdabcdabcd, fapi2::IGNORE_HW_ERROR, true}, // invalid unit 0 address + { scom_targets[myEX1], 0x000F0166, 0xabcdabcdabcdabcd, fapi2::IGNORE_HW_ERROR, true}, // invalid address range for target + { scom_targets[myEX1], 0x21000000 ,0x7676767676767676, fapi2::DO_NOT_DO_WAKEUP, false}, // pervasive addr does not req wakeup + { scom_targets[myEX5], 0x20010A02, 0x9191919191919191, fapi2::DO_NOT_DO_WAKEUP, false}, + { scom_targets[myEX5], 0x13040002, 0xabcdabcdabcdabcd, fapi2::DO_NOT_DO_WAKEUP, true}, // invalid unit 0 address + { scom_targets[myEX1], 0x000F0166, 0xabcdabcdabcdabcd, fapi2::DO_NOT_DO_WAKEUP, true}, // invalid address range for target }; const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]); @@ -422,13 +443,14 @@ public: //only run if the target exists if(test_data[x].target == NULL) { + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes> test target is null, continuing" ); continue; } // check to see if the target is functional.. if not.. skip this target else if (test_data[x].target-> getAttr<TARGETING::ATTR_HWAS_STATE>().functional != true) { - TRACDCOMP( g_trac_scom, "ScomTest::test_translate_scom_EX> Target %d is not functional", x ); + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes> Target %d is not functional", x ); continue; } @@ -439,24 +461,33 @@ public: l_err = deviceWrite( test_data[x].target, &(test_data[x].data), op_size, - DEVICE_SCOM_ADDRESS(test_data[x].addr) ); - if( l_err ) + DEVICE_SCOM_ADDRESS(test_data[x].addr, test_data[x].mode) + ); + + if (!test_data[x].expectErr) { - // last 2 writes have expected failure conditions. - if ((x == NUM_ADDRS-1) || (x == NUM_ADDRS-2)) + if( l_err ) { - TRACDCOMP( g_trac_scom, "ScomTest::test_translate_EX.. Expected Error log returned> " ); + TRACFCOMP(g_trac_scom, "ScomTest::test_opModes> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() ); + TS_FAIL( "ScomTest::test_opModes> ERROR : Unexpected error log from write1" ); + fails++; + errlCommit(l_err,SCOM_COMP_ID); + } + } + else + { + if( l_err ) + { + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes.. Expected Error log returned> " ); } else { - TRACFCOMP(g_trac_scom, "ScomTest::test_translate_scom_EX> [%d] Write: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() ); - TS_FAIL( "ScomTest::test_translate_EX> ERROR : Unexpected error log from write1" ); + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes.. Expected Error log and did not get one for addr 0x%X " ,test_data[x].addr ); + TS_FAIL( "ScomTest::test_opModes> ERROR : Expected Error log and did not get one" ); fails++; - errlCommit(l_err,SCOM_COMP_ID); } - - delete l_err; } + delete l_err; } // allocate space for read data @@ -466,11 +497,12 @@ public: // read all the test registers - for( uint64_t x = 0; x < NUM_ADDRS-2; x++ ) + for( uint64_t x = 0; x < NUM_ADDRS; x++ ) { //only run if the target exists if(test_data[x].target == NULL) { + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes> test target is null, continueing" ); continue; } @@ -480,25 +512,40 @@ public: l_err = deviceRead( test_data[x].target, &(read_data[x]), op_size, - DEVICE_SCOM_ADDRESS(test_data[x].addr) ); - - if( l_err ) + DEVICE_SCOM_ADDRESS(test_data[x].addr, test_data[x].mode)); + if (!test_data[x].expectErr) { - TRACFCOMP(g_trac_scom, "ScomTest::test_translate_scom_EX> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() ); - TS_FAIL( "ScomTest::test_translate_scom_EX> ERROR : Unexpected error log from write1" ); - fails++; - errlCommit(l_err,SCOM_COMP_ID); + if( l_err ) + { + TRACFCOMP(g_trac_scom, "ScomTest::test_opModes> [%d] Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() ); + TS_FAIL( "ScomTest::test_opModes> ERROR : Unexpected error log from write1" ); + fails++; + errlCommit(l_err,SCOM_COMP_ID); + } + else if((read_data[x]) != (test_data[x].data)) + { + TRACFCOMP(g_trac_scom, "ScomTest::test_opModes> [%d] Read: Data miss-match : addr=0x%X, read_data=0x%llx, write_data=0x%llx", x, test_data[x].addr, read_data[x], test_data[x].data); + TS_FAIL( "ScomTest::test_opModes> ERROR : Data miss-match between read and expected data" ); + fails++; + } } - else if((read_data[x]) != (test_data[x].data)) + else { - TRACFCOMP(g_trac_scom, "ScomTest::test_translate_scom_EX> [%d] Read: Data miss-match : addr=0x%X, read_data=0x%llx, write_data=0x%llx", x, test_data[x].addr, read_data[x], test_data[x].data); - TS_FAIL( "ScomTest::test_translate_scom_EX> ERROR : Data miss-match between read and expected data" ); - fails++; + if( l_err ) + { + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes.. Expected Error log returned> " ); + } + else + { + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes.. Expected Error log and did not get one for addr 0x%X " ,test_data[x].addr ); + TS_FAIL( "ScomTest::test_opModes> ERROR : Expected Error log and did not get one" ); + fails++; + } } - + delete l_err; } - TRACFCOMP( g_trac_scom, "ScomTest::test_translateScom_EX> %d/%d fails", fails, total ); + TRACFCOMP( g_trac_scom, "ScomTest::test_opModes> %d/%d fails", fails, total ); } diff --git a/src/usr/scom/scom.mk b/src/usr/scom/scom.mk index 5c8cbacbc..ec0f57a19 100644 --- a/src/usr/scom/scom.mk +++ b/src/usr/scom/scom.mk @@ -26,7 +26,7 @@ VPATH += ${ROOTPATH}/src/import/chips/p9/common/scominfo/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/scominfo/ - +EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/ # Local Objects OBJS += scom.o OBJS += scomtrans.o diff --git a/src/usr/scom/scomtrans.C b/src/usr/scom/scomtrans.C index c8dadd309..2c87dcea3 100644 --- a/src/usr/scom/scomtrans.C +++ b/src/usr/scom/scomtrans.C @@ -52,6 +52,7 @@ #include <initservice/initserviceif.H> #include <p9_scom_addr.H> #include <p9_scominfo.H> +#include <hw_access_def.H> #if __HOSTBOOT_RUNTIME #include "handleSpecialWakeup.H" @@ -179,8 +180,10 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, TARGETING::Target* l_parentChip = const_cast<TARGETING::Target *>(TARGETING::getParentChip(i_target)); uint64_t l_addr = va_arg(i_args,uint64_t); + //if opMode is not specified as an argument va_arg will return NULL which is 0 + uint64_t l_opMode = va_arg(i_args,uint64_t); - l_err = scomTranslate(i_target, l_addr, l_target_SW); + l_err = scomTranslate(i_target, l_addr, l_target_SW, l_opMode); if (l_err == NULL) @@ -198,7 +201,9 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, // @todo RTC:124196 need to move this to a more general location so that // the disable occurs after the HBRT is complete. #if __HOSTBOOT_RUNTIME - if(l_target_SW != NULL && !g_wakeupInProgress) + if(!(l_opMode & fapi2::DO_NOT_DO_WAKEUP) && + (l_target_SW != NULL) && + !g_wakeupInProgress) { g_wakeupInProgress = true; errlHndl_t l_errSW = NULL; @@ -207,7 +212,7 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, if(l_err != NULL && l_errSW) { - TRACFCOMP(g_trac_scom,"Disable p8_cpu_special_wakeup ERROR"); + TRACFCOMP(g_trac_scom,"Disable p9_cpu_special_wakeup ERROR"); // capture the target data in the elog ERRORLOG::ErrlUserDetailsTarget(l_target_SW).addToLog(l_errSW); @@ -227,7 +232,8 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, ////////////////////////////////////////////////////////////////////////////// errlHndl_t scomTranslate(TARGETING::Target * &i_target, uint64_t & io_addr, - TARGETING::Target * io_target_SW) + TARGETING::Target * io_target_SW, + uint64_t i_opMode) { errlHndl_t l_err = NULL; @@ -239,7 +245,8 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target, l_err = p9_translation(i_target, l_type, io_addr, - io_target_SW); + io_target_SW, + i_opMode); return l_err; } @@ -249,7 +256,8 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target, errlHndl_t p9_translation (TARGETING::Target * &i_target, TARGETING::TYPE i_type, uint64_t &io_addr, - TARGETING::Target * io_target_SW) + TARGETING::Target * io_target_SW, + uint64_t i_opMode) { errlHndl_t l_err = NULL; do { @@ -302,8 +310,9 @@ errlHndl_t p9_translation (TARGETING::Target * &i_target, bool isFSP_HBRT = INITSERVICE::spBaseServicesEnabled(); if(((i_type == TARGETING::TYPE_EX) || (i_type == TARGETING::TYPE_CORE)) && - (!g_wakeupInProgress) && (!isFSP_HBRT) ) + (!g_wakeupInProgress) && (!isFSP_HBRT) && !(i_opMode & fapi2::DO_NOT_DO_WAKEUP) ) { + TRACFCOMP(g_trac_scom,"Determining if Special Wakeup is needed.."); bool l_needsWakeup = true; for(uint16_t i = 0; i < l_scomPairings.size(); i++) { @@ -315,6 +324,7 @@ errlHndl_t p9_translation (TARGETING::Target * &i_target, } if(l_needsWakeup) { + TRACFCOMP(g_trac_scom,"Special wakeup required, starting now.."); g_wakeupInProgress = true; l_err = handleSpecialWakeup(i_target,true); diff --git a/src/usr/scom/scomtrans.H b/src/usr/scom/scomtrans.H index d89874ce1..4e63b9453 100644 --- a/src/usr/scom/scomtrans.H +++ b/src/usr/scom/scomtrans.H @@ -68,11 +68,13 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, * @param[in] i_target SCom target * @param[in|out] io_addr SCom address * @param[in|out] io_target_SW target for SW + * @param[in] i_opMode Defaults to 0 (Standard) * @return errlHndl_t */ errlHndl_t scomTranslate(TARGETING::Target * &i_target, uint64_t & io_addr, - TARGETING::Target * io_target_SW); + TARGETING::Target * io_target_SW, + uint64_t i_opMode = 0); /** * @brief This function translates a scom address using the @@ -82,12 +84,14 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target, * @param[in] i_type Type of the target * @param[in|out] io_addr Address to be translated * @param[in|out] io_target_SW SW target for HBRT + * @param[in] i_opMode Defaults to 0 (Standard) * @return errlHndl_t */ errlHndl_t p9_translation (TARGETING::Target * &i_target, TARGETING::TYPE i_type, uint64_t &io_addr, - TARGETING::Target * io_target_SW); + TARGETING::Target * io_target_SW, + uint64_t i_opMode = 0); /** * @brief This function translates a scom address using the diff --git a/src/usr/scom/test/scomtest.H b/src/usr/scom/test/scomtest.H index 2d495ff09..fce8c8ac2 100644 --- a/src/usr/scom/test/scomtest.H +++ b/src/usr/scom/test/scomtest.H @@ -48,7 +48,8 @@ namespace SCOM { extern errlHndl_t scomTranslate(TARGETING::Target* &i_target, uint64_t &io_addr, - TARGETING::Target* io_target_SW); + TARGETING::Target* io_target_SW, + uint64_t i_opMode = 0); } class ScomTest: public CxxTest::TestSuite { |

