diff options
| author | Dan Crowell <dcrowell@us.ibm.com> | 2018-10-11 09:22:47 -0500 |
|---|---|---|
| committer | William G. Hoffa <wghoffa@us.ibm.com> | 2018-10-11 17:53:08 -0500 |
| commit | 627379aeaa27e30d66ebb0aecf218708d465162c (patch) | |
| tree | 14782327cf978a2f05efdc74339990a8f8fceb37 /src/usr/sio | |
| parent | 30bd2ff53aa13e2d01bf02405f3e6eed3e576454 (diff) | |
| download | blackbird-hostboot-627379aeaa27e30d66ebb0aecf218708d465162c.tar.gz blackbird-hostboot-627379aeaa27e30d66ebb0aecf218708d465162c.zip | |
sio: Add test for availability - LPC error tweak
Some components can continue to operate in the face of the SuperIO
controller being unavailable on the LPC bus (specifically, the UART and
boot flag processing). Other components require it present (AST-based
SFC implementations and the AST mailbox). Components in the latter
category can just fail with an errl when they attempt to access the
controller, but for those in the former category we add an isAvailable()
function in the SIO namespace to sidestep dealing with errors.
Specifically, isAvailable() tests for the expected error when the
SuperIO controller is disabled, and returns an errlHndl_t if any other
error occurs. This way true LPC errors are propagated to the caller to
commit as desired.
Change-Id: Ib94ceabfd4f4e9c63c114cfe3db3c954dbb6d6e5
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67315
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: ANDREW R. JEFFERY <andrewrj@au1.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/sio')
| -rwxr-xr-x | src/usr/sio/siodd.C | 73 | ||||
| -rw-r--r-- | src/usr/sio/siodd.H | 4 |
2 files changed, 55 insertions, 22 deletions
diff --git a/src/usr/sio/siodd.C b/src/usr/sio/siodd.C index 5301d9e1c..e6a4db66c 100755 --- a/src/usr/sio/siodd.C +++ b/src/usr/sio/siodd.C @@ -37,6 +37,9 @@ #include <hbotcompid.H> #include <stdarg.h> #include <targeting/common/target.H> +#include <lpc/lpc_reasoncodes.H> + +#include <console/consoleif.H> // Trace definition trace_desc_t* g_trac_sio = NULL; @@ -191,32 +194,52 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WRITE, TARGETING::TYPE_PROC, ahbSioWriteDD ); -//function to unlock superIO password register -void SioDD::unlock_SIO(TARGETING::Target* i_target) +errlHndl_t SIO::isAvailable(bool& available) { uint8_t l_byte = SIO::SIO_PASSWORD_REG; - errlHndl_t l_err = NULL; - do - { - // Unlock the SIO registers - // (write 0xA5 password to offset 0x2E two times) size_t l_len = sizeof(uint8_t); - l_err = deviceWrite(i_target, - &l_byte, - l_len, - DEVICE_LPC_ADDRESS(LPC::TRANS_IO, SIO::SIO_ADDR_REG_2E)); - if(l_err) { break; } - l_err = deviceWrite(i_target, - &l_byte, - l_len, + errlHndl_t l_err = NULL; + + l_err = deviceWrite(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &l_byte, l_len, DEVICE_LPC_ADDRESS(LPC::TRANS_IO, SIO::SIO_ADDR_REG_2E)); - } while(0); if (l_err) { - TRACFCOMP(g_trac_sio,"Error in unlocking SIO password register\n"); - errlCommit(l_err, SIO_COMP_ID); + /* Check if we got the expected error for the SIO being locked out */ + if( l_err->reasonCode() == LPC::RC_LPCHC_SYNCAB_ERROR ) + { + available = false; + /* The error is expected, drop it */ + delete l_err; + l_err = NULL; + } + } + else + { + available = true; } + + return l_err; +} + +//function to unlock superIO password register +errlHndl_t SioDD::unlock_SIO(TARGETING::Target* i_target) +{ + uint8_t l_byte = SIO::SIO_PASSWORD_REG; + size_t l_len = sizeof(uint8_t); + errlHndl_t l_err = NULL; + int again = 1; + + do + { + // Unlock the SIO registers (write 0xA5 password to offset 0x2E two times) + l_err = deviceWrite(i_target, &l_byte, l_len, + DEVICE_LPC_ADDRESS(LPC::TRANS_IO, + SIO::SIO_ADDR_REG_2E)); + } while(!l_err && again--); + + return l_err; } //SioDD constructor @@ -225,7 +248,16 @@ SioDD::SioDD(TARGETING::Target* i_target) assert(i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL); mutex_init(&iv_sio_mutex); iv_prev_dev = 0x00; - unlock_SIO(i_target); + + errlHndl_t err = unlock_SIO(i_target); + bool failed = (err != NULL); + delete err; + + /* Unlocked very early, so make some noise if we fail */ + if (failed) + { + printk("SuperIO unlock failed! Expect future errors\n"); + } } //SioDD destructor @@ -279,8 +311,7 @@ errlHndl_t SioDD::_readSIO(TARGETING::Target* i_target, //function to change logical device in SIO errlHndl_t SioDD::changeDevice(TARGETING::Target* i_target, uint8_t i_dev) { - uint8_t l_reg = SIO::SIO_DEVICE_SELECT_REG; - return _writeSIO(i_target, l_reg, &i_dev); + return _writeSIO(i_target, SIO::SIO_DEVICE_SELECT_REG, &i_dev); } //function to read from SIO register diff --git a/src/usr/sio/siodd.H b/src/usr/sio/siodd.H index 664935921..86821d466 100644 --- a/src/usr/sio/siodd.H +++ b/src/usr/sio/siodd.H @@ -167,8 +167,10 @@ class SioDD /** * @brief Unlock SIO password register * @param[in] i_target: SIO target + * + * @return Error from operation */ - void unlock_SIO(TARGETING::Target* i_target); + errlHndl_t unlock_SIO(TARGETING::Target* i_target); /** * @brief Previous device accessed by SIO |

