summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C300
1 files changed, 144 insertions, 156 deletions
diff --git a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C
index ba2240e8a..7409c41db 100644
--- a/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C
+++ b/src/import/chips/p9/procedures/hwp/cache/p9_l3err_linedelete.C
@@ -22,17 +22,21 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-//------------------------------------------------------------------------------
-// *|
-// *! TITLE : p9_l3err_linedelete.C
-// *! DESCRIPTION : Delete the L3 error cache line according to the error extraction information.
-// *!
-// *! OWNER NAME : Alex Taft Email: amtaft@us.ibm.com
-// *!
-// *! ADDITIONAL COMMENTS :
-// *! See header file for additional comments.
-//------------------------------------------------------------------------------
+///----------------------------------------------------------------------------
+///
+/// @file p9_l3err_linedelete.H
+///
+/// @brief Delete the L3 error cache line according to the error extraction
+/// information.
+/// See header file for detailed description.
+///
+/// *HWP HWP Owner : Alex Taft <amtaft@us.ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Quad
+/// *HWP Consumed by : PRDF
+/// *HWP Level : 3
+///----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Includes
@@ -46,161 +50,145 @@
const uint32_t BUSY_POLL_DELAY_IN_NS = 10000000; // 10ms
const uint32_t BUSY_POLL_DELAY_IN_CYCLES = 20000000; // 10ms, assumming 2GHz
-extern "C"
-{
-
//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------
+///
+/// @brief Utility function to check for a L3 purge operation to be completed.
+/// This function polls the EX_PRD_PURGE_REG_L3_REQ bit of
+/// EX_PRD_PURGE_REG.
+/// - If this bit is clear before the input loop threshold is
+/// reached, it returns FAPi2_RC_SUCCESS.
+/// - Otherwise, it returns an error code.
+///
+/// @param[in] i_target => EX chiplet target
+/// @param[in] i_busyCount => Max busy count waiting for PURGE to complete.
+/// @param[out] o_prdPurgeReg => EX_PRD_PURGE_CMD_REG value.
+///
+fapi2::ReturnCode l3PurgeCompleteCheck(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const uint64_t i_busyCount,
+ fapi2::buffer<uint64_t>& o_prdPurgeReg)
+{
+ FAPI_DBG("Entering l3PurgeCompleteCheck");
-//------------------------------------------------------------------------------
-// HWP entry point
-//------------------------------------------------------------------------------
- fapi2::ReturnCode p9_l3err_linedelete(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
- const p9_l3err_extract_err_data& i_err_data,
- const uint64_t p9_l3err_linedelete_TryBusyCounts)
+ // Wait EX_PRD_PURGE_CMD_REG_BUSY bit for a max input counter time
+ uint64_t l_loopCount = 0;
+
+ do
{
+ FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_REG, o_prdPurgeReg),
+ "Error from getScom EX_PRD_PURGE_REG");
- uint8_t member = 0;
- uint16_t cgc = 0;
- uint64_t busy_reg_counter = 0;
- fapi2::buffer<uint64_t> l_l3_l3cerrs_prd_purge_reg;
-
- bool reg_busy = 0;
- bool prd_purge_busy = 1;
-
- // mark function entry
- FAPI_DBG("Entering p9_l3err_linedelete...");
-
-
- // +---------------------------+
- // | L3 Line Delete Scom |
- // +---------------------------+
- // |Bit(s)| Data |
- // +------+--------------------+
- // | 0 | Trigger |
- // +------+--------------------+
- // | 1:4 | Purge type (ld=0x2)|
- // +------+--------------------+
- // | 5:8 | Don't care |
- // +------+--------------------+
- // | 9 | Busy Error |
- // +------+--------------------+
- // |12:16 | Member (1 of 20) |
- // +------+--------------------+
- // |17:28 | CGC (addr 45:56) |
- // +------+--------------------+
- // |29:63 | Don't care |
- // +------+--------------------+
-
-
- member = i_err_data.member;
- cgc = i_err_data.hashed_real_address_45_56;
-
- // EXP.L3.L3_MISC.L3CERRS.PRD_PURGE_REG
- // Write member, cgc address into PRD Purge Engine Command Register
- // SCOM Addr: 0x000000001001180E
- // bit 0 is the trigger, the act of writing this bit to 1 sets off the line delete
- // bits 1:4 is ttype 0b0010 = line delete
- // bits 12:16 is the member
- // bits 17:28 is the cgc address
-
-
- FAPI_DBG("p9_l3err_linedelete_TryBusyCounts: %ld", p9_l3err_linedelete_TryBusyCounts);
-
- // wait reg_busy bit for a max counter time which is defined by user
- do
+ // Check the EX_PRD_PURGE_CMD_REG_BUSY bit from scom register
+ if ( !o_prdPurgeReg.getBit(EX_PRD_PURGE_REG_L3_REQ) )
{
- FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg),
- "Error from getScom (l_l3_l3cerrs_prd_purge_reg)");
- FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg);
-
- // get the reg_busy bit from scom register
- l_l3_l3cerrs_prd_purge_reg.extractToRight<EX_PRD_PURGE_REG_L3_REQ, 1>(reg_busy);
-
- if (reg_busy == 0)
- {
- prd_purge_busy = 0;
- break;
- }
- else
- {
- busy_reg_counter = busy_reg_counter + 1;
- FAPI_DBG("reg_busy = %u, wait for 10ms and try again, remaining cout: %u!",
- reg_busy, busy_reg_counter);
- // Delay for 10ms
- fapi2::delay(BUSY_POLL_DELAY_IN_NS, BUSY_POLL_DELAY_IN_CYCLES);
- }
+ // PURGE is done, get out
+ break;
}
- while (busy_reg_counter < p9_l3err_linedelete_TryBusyCounts);
-
-
- // if the reg_busy is still 1 during the counter time
- // error occurs
- FAPI_ASSERT(!prd_purge_busy,
- fapi2::P9_L3ERR_LINE_DELETE_REG_BUSY().
- set_TARGET(i_target),
- "Error: hit timeout. PRD_PURGE_REG still working on a previous purge.");
-
- FAPI_DBG("reg_busy = %u", reg_busy);
-
-
- // if reg_busy is 0
- // write trigger, type, cgc address, member into PRD Purge Engine Command Register
- if (reg_busy == 0)
+ else
{
-
- l_l3_l3cerrs_prd_purge_reg.insertFromRight<EX_PRD_PURGE_REG_L3_MEMBER, EX_PRD_PURGE_REG_L3_MEMBER_LEN>(member);
- l_l3_l3cerrs_prd_purge_reg.insertFromRight<EX_PRD_PURGE_REG_L3_DIR_ADDR, EX_PRD_PURGE_REG_L3_DIR_ADDR_LEN>(cgc);
-
- l_l3_l3cerrs_prd_purge_reg.insertFromRight<EX_PRD_PURGE_REG_L3_REQ, 1>(1);
- l_l3_l3cerrs_prd_purge_reg.insertFromRight<EX_PRD_PURGE_REG_L3_TTYPE, EX_PRD_PURGE_REG_L3_TTYPE_LEN>(0x2);
-
- FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg);
- FAPI_TRY(fapi2::putScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg),
- "Error from putScom (l_l3_l3cerrs_prd_purge_reg)");
-
- do
- {
- FAPI_TRY(fapi2::getScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg),
- "Error from getScom (l_l3_l3cerrs_prd_purge_reg)");
- FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg);
-
- // get the reg_busy bit from scom register
- l_l3_l3cerrs_prd_purge_reg.extractToRight<EX_PRD_PURGE_REG_L3_REQ, 1>(reg_busy);
-
- if (reg_busy == 0)
- {
- prd_purge_busy = 0;
- break;
- }
- else
- {
- busy_reg_counter = busy_reg_counter + 1;
- FAPI_DBG("reg_busy = %u, wait for 10ms and try again, remaining cout: %u!",
- reg_busy, busy_reg_counter);
- // Delay for 10ms
- fapi2::delay(BUSY_POLL_DELAY_IN_NS, BUSY_POLL_DELAY_IN_CYCLES);
- }
- }
- while (busy_reg_counter < p9_l3err_linedelete_TryBusyCounts);
-
- // if the reg_busy is still 1 during the counter time
- // error occurs
- FAPI_ASSERT(!prd_purge_busy,
- fapi2::P9_L3ERR_LINE_DELETE_REG_BUSY().
- set_TARGET(i_target),
- "Error: PRD_PURGE_REG indicates the ie compelteion bit was not set yet, the PRD Purge Engine Command Regiter write failed.");
-
- FAPI_DBG("Writing PRD Purge Engine Command Register busy bit status, reg_busy = %u", reg_busy);
- // poll the busy bit completed
-
+ l_loopCount++;
+ // Delay for 10ms
+ FAPI_TRY(fapi2::delay(BUSY_POLL_DELAY_IN_NS,
+ BUSY_POLL_DELAY_IN_CYCLES),
+ "Fapi Delay call failed.");
}
+ }
+ while (l_loopCount < i_busyCount);
+
+ // Error out if still busy
+ FAPI_ASSERT(l_loopCount < i_busyCount,
+ fapi2::P9_L3ERR_LINE_DELETE_REG_BUSY()
+ .set_TARGET(i_target)
+ .set_COUNT_THRESHOLD(i_busyCount)
+ .set_PRD_PURGE_REG(o_prdPurgeReg),
+ "Error: PRD_PURGE_CMD_REG_BUSY exceeds limit count of %d.",
+ i_busyCount);
+
+fapi_try_exit:
+ FAPI_DBG("Exiting l3PurgeCompleteCheck - Counter: %d; prdPurgeReg: 0x%.16llX",
+ l_loopCount, o_prdPurgeReg);
+ return fapi2::current_err;
+}
- // mark HWP exit
- fapi_try_exit:
- FAPI_INF("Exiting p9_l3err_linedelete...");
- return fapi2::current_err;
- } // p9_l3err_extract
+//------------------------------------------------------------------------------
+// HWP entry point
+//------------------------------------------------------------------------------
+// See doxygen in header file
+// TODO: RTC 178071
+// See if with some small refactoring we could just call/share the p9_l3_flush
+// HWP code/errors to implement this routine?
+fapi2::ReturnCode p9_l3err_linedelete(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
+ const p9_l3err_extract_err_data& i_err_data,
+ const uint64_t i_busyCount)
+{
-} // extern "C
+ // mark function entry
+ FAPI_DBG("Entering p9_l3err_linedelete: i_busyCount: %ld", i_busyCount);
+
+ fapi2::buffer<uint64_t> l_l3_l3cerrs_prd_purge_reg;
+
+ // +---------------------------+
+ // | L3 Line Delete Scom |
+ // +---------------------------+
+ // |Bit(s)| Data |
+ // +------+--------------------+
+ // | 0 | Trigger |
+ // +------+--------------------+
+ // | 1:4 | Purge type (ld=0x2)|
+ // +------+--------------------+
+ // | 5:8 | Don't care |
+ // +------+--------------------+
+ // | 9 | Busy Error |
+ // +------+--------------------+
+ // |12:16 | Member (1 of 20) |
+ // +------+--------------------+
+ // |17:28 | CGC (addr 45:56) |
+ // +------+--------------------+
+ // |29:63 | Don't care |
+ // +------+--------------------+
+
+ // EXP.L3.L3_MISC.L3CERRS.PRD_PURGE_REG
+ // Write member, cgc address into PRD Purge Engine Command Register
+ // SCOM Addr: 0x000000001001180E
+ // bit 0 is the trigger, the act of writing this bit to 1 sets off the line delete
+ // bits 1:4 is ttype 0b0010 = line delete
+ // bits 12:16 is the member
+ // bits 17:28 is the cgc address
+
+ // Make sure there's no current purge is in progress
+ FAPI_TRY(l3PurgeCompleteCheck(i_target, i_busyCount,
+ l_l3_l3cerrs_prd_purge_reg),
+ "Error returned from l3PurgeCompleteCheck()");
+ FAPI_DBG("l_l3_l3cerrs_prd_purge_reg: 0x%.16llX",
+ l_l3_l3cerrs_prd_purge_reg);
+
+
+ l_l3_l3cerrs_prd_purge_reg.insertFromRight
+ <EX_PRD_PURGE_REG_L3_MEMBER, EX_PRD_PURGE_REG_L3_MEMBER_LEN>
+ (i_err_data.member);
+ l_l3_l3cerrs_prd_purge_reg.insertFromRight
+ <EX_PRD_PURGE_REG_L3_DIR_ADDR, EX_PRD_PURGE_REG_L3_DIR_ADDR_LEN>
+ (i_err_data.hashed_real_address_45_56);
+ l_l3_l3cerrs_prd_purge_reg.insertFromRight<EX_PRD_PURGE_REG_L3_REQ, 1>(1);
+ l_l3_l3cerrs_prd_purge_reg.insertFromRight
+ <EX_PRD_PURGE_REG_L3_TTYPE, EX_PRD_PURGE_REG_L3_TTYPE_LEN>(0x2);
+
+ FAPI_DBG("l_l3_l3cerrs_prd_purge_reg_data: %#lx", l_l3_l3cerrs_prd_purge_reg);
+ FAPI_TRY(fapi2::putScom(i_target, EX_PRD_PURGE_REG, l_l3_l3cerrs_prd_purge_reg),
+ "Error from putScom (l_l3_l3cerrs_prd_purge_reg)");
+
+ // Verify purge operation is complete
+ FAPI_TRY(l3PurgeCompleteCheck(i_target, i_busyCount,
+ l_l3_l3cerrs_prd_purge_reg),
+ "Error returned from l3PurgeCompleteCheck()");
+ FAPI_DBG("l_l3_l3cerrs_prd_purge_reg: 0x%.16llX",
+ l_l3_l3cerrs_prd_purge_reg);
+
+ // mark HWP exit
+fapi_try_exit:
+ FAPI_INF("Exiting p9_l3err_linedelete...");
+ return fapi2::current_err;
+} // p9_l3err_extract
OpenPOWER on IntegriCloud