diff options
| author | crgeddes <crgeddes@us.ibm.com> | 2016-03-31 10:57:35 -0500 |
|---|---|---|
| committer | Stephen Cprek <smcprek@us.ibm.com> | 2016-04-21 13:51:39 -0500 |
| commit | d32a58cf2c6d9c3b7698a5a088f120b67ee287fc (patch) | |
| tree | f2c3a275f5336a35b84d43fac0f4293a1b531d15 /src | |
| parent | fe1d7934857366cab8695381ac6a7f5e3b7ed29a (diff) | |
| download | talos-hostboot-d32a58cf2c6d9c3b7698a5a088f120b67ee287fc.tar.gz talos-hostboot-d32a58cf2c6d9c3b7698a5a088f120b67ee287fc.zip | |
Implement DO_NOT_WAKEUP opMode for Scom access
During runtime we occasionally will read scoms from various chiplets.
Usually if the chiplet is in winkle mode (stopped, idle, etc) then we will
wake it up. If this opmode is set, it is indicating the attempted read is not
very important and not worth the time/energy to wake up the chiplet.
Change-Id: Ieaaffe42fda3459e0295597fcf41c07bbaee72b4
RTC: 150454
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22986
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
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 { |

