diff options
author | whs <whs@us.ibm.com> | 2016-05-04 05:11:48 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-05-04 11:46:17 -0400 |
commit | 959315cb542fbb9f1386cabea0123ee02495c1fb (patch) | |
tree | 9a2ae390adae81e138869afb3cc8a62dc1a46c59 | |
parent | 21beca702140bf104b6cb769564ea7f3d105f2b5 (diff) | |
download | talos-hostboot-959315cb542fbb9f1386cabea0123ee02495c1fb.tar.gz talos-hostboot-959315cb542fbb9f1386cabea0123ee02495c1fb.zip |
SBE FIFO logic between Hostboot and SBE not working as expected
replace SBE_FIFO_UPFIFO_DATA_IN with SBE_FIFO_DNFIFO_DATA_OUT.
Optimize reading doorbell on download, close potential timing problem.
Ignore EOT dummy word on download.
Change-Id: Ia55c977292c499866d189aa2fe4a6b59404b9991
CQ: SW351690
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24073
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/usr/sbeio/sbe_fifodd.C | 41 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_fifodd.H | 13 |
2 files changed, 35 insertions, 19 deletions
diff --git a/src/usr/sbeio/sbe_fifodd.C b/src/usr/sbeio/sbe_fifodd.C index 81b7aaf0d..637149a0f 100644 --- a/src/usr/sbeio/sbe_fifodd.C +++ b/src/usr/sbeio/sbe_fifodd.C @@ -244,14 +244,20 @@ errlHndl_t readResponse(TARGETING::Target * i_target, // receive words until EOT, but do not exceed response buffer size do { - // EOT? - // Checking at top of the loop in case EOT is sent before any data. - uint32_t l_eotStatus = 0; - errl = readFsi(i_target,SBE_FIFO_DNFIFO_STATUS,&l_eotStatus); - if (errl) break; - if ( l_eotStatus & DNFIFO_STATUS_DEQUEUED_EOT_FLAG) + // Wait for data to be ready to receive (download) or if the EOT + // has been sent. If not EOT, then data ready to receive. + uint32_t l_status = 0; + errl = waitDnFifoReady(i_target,l_status); + if ( l_status & DNFIFO_STATUS_DEQUEUED_EOT_FLAG) { l_EOT = true; + // ignore EOT dummy word + if (l_recWords >= (sizeof(statusHeader)/sizeof(uint32_t)) ) + { + l_pReceived--; + l_recWords--; + l_last = o_pFifoResponse[l_recWords-1]; + } break; } @@ -261,12 +267,8 @@ errlHndl_t readResponse(TARGETING::Target * i_target, break; //ran out of receive buffer before EOT } - // check that a downstream word is ready to receive - errl = waitDnFifoReady(i_target); - if (errl) break; - // read next word - errl = readFsi(i_target,SBE_FIFO_UPFIFO_DATA_IN,&l_last); + errl = readFsi(i_target,SBE_FIFO_DNFIFO_DATA_OUT,&l_last); if (errl) break; *l_pReceived = l_last; //copy to returned output buffer @@ -279,6 +281,7 @@ errlHndl_t readResponse(TARGETING::Target * i_target, // At this point, // l_recWords of words received. // l_pReceived points to 1 word past last word received. + // l_last has last word received, which is "distance" to status // EOT is expected before running out of response buffer if (!l_EOT) @@ -425,8 +428,13 @@ errlHndl_t readResponse(TARGETING::Target * i_target, /** * @brief wait for data in downstream fifo to receive + * or hit EOT. + * + * On return, either a valid word is ready to read, + * or the EOT will be set in the returned doorbell status. */ -errlHndl_t waitDnFifoReady(TARGETING::Target * i_target) +errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, + uint32_t & o_status) { errlHndl_t errl = NULL; @@ -434,15 +442,16 @@ errlHndl_t waitDnFifoReady(TARGETING::Target * i_target) uint64_t l_elapsed_time_ns = 0; uint64_t l_addr = SBE_FIFO_DNFIFO_STATUS; - uint32_t l_data = 0; do { // read dnstream status to see if data ready to be read - errl = readFsi(i_target,l_addr,&l_data); + // or if has hit the EOT + errl = readFsi(i_target,l_addr,&o_status); if (errl) break; - if ( !(l_data & DNFIFO_STATUS_FIFO_EMPTY) ) + if ( !(o_status & DNFIFO_STATUS_FIFO_EMPTY) || + (o_status & DNFIFO_STATUS_DEQUEUED_EOT_FLAG) ) { break; } @@ -451,7 +460,7 @@ errlHndl_t waitDnFifoReady(TARGETING::Target * i_target) if (l_elapsed_time_ns >= MAX_UP_FIFO_TIMEOUT_NS ) { SBE_TRACF(ERR_MRK "waitDnFifoReady: " - "timeout waiting for upstream FIFO to be not full"); + "timeout waiting for downstream FIFO to be not full"); //TODO RTC 149454 implement error recovery and ffdc diff --git a/src/usr/sbeio/sbe_fifodd.H b/src/usr/sbeio/sbe_fifodd.H index 657210560..4461b558e 100644 --- a/src/usr/sbeio/sbe_fifodd.H +++ b/src/usr/sbeio/sbe_fifodd.H @@ -157,7 +157,9 @@ namespace SBEIO { statusHeader status; uint32_t pcbpibStatus; // only present on errors - uint32_t status_distance; //will be last word received + // ffdc will go here on errors + uint32_t status_distance; // distance to status + uint32_t EOT; // dummy EOT word to ignore fifoPutScomResponse() {} } PACKED; @@ -172,7 +174,9 @@ namespace SBEIO uint64_t data; // Data (0..31) + (32..63) statusHeader status; uint32_t pcbpibStatus; // only present on errors - uint32_t status_distance; //will be last word received + // ffdc will go here on errors + uint32_t status_distance; // distance to status + uint32_t EOT; // dummy EOT word to ignore fifoGetScomResponse() {} } PACKED; @@ -268,11 +272,14 @@ namespace SBEIO /** * @brief poll until downlift Fifo has a value to read + * or has hit EOT. * * @param[in] i_target Target to access + * @param[out] o_status Down load door bell status * @return errlHndl_t Error log handle on failure. */ - errlHndl_t waitDnFifoReady(TARGETING::Target * i_target); + errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, + uint32_t & o_status); /** * @brief encapulate FSI read |