summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorCHRISTINA L. GRAVES <clgraves@us.ibm.com>2016-12-01 11:22:11 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2017-02-24 07:29:54 -0500
commit1444b4766dc16f863a87e83190a3e057c2cb532e (patch)
tree3a05fdeb8ae3d59d23797dab78016b15a4f1861e /src/import/chips
parent4b3cf2ee74ed938823783eafdec354ace91a4a2c (diff)
downloadtalos-sbe-1444b4766dc16f863a87e83190a3e057c2cb532e.tar.gz
talos-sbe-1444b4766dc16f863a87e83190a3e057c2cb532e.zip
Added workaround for INT unit for DD1
Made changes to NX unit Added in DD2 changes for NPU Removed the HCA funciton Added in correct timing waits Added attributes for DD2 fixes Added in flushing the secure boot register for PSIHB Added in fix for PHB5 being based on PCI2 Removed attributes for DD2 fixes Readded attributes for DD2 fixes with EC_FEATURE Fixed the attributes from being opposite in the file Reduced the size of p9_sbe_check_quiesce Don't quiesce CAPP unless initialized Made fix for having 2MB instead of 6KB for Notify Port Page Fixing a problem with INTP on PHYP and comments from Christian/Raja Change-Id: I83a8322898a7379ff7bdfdfcd846b63b40278e45 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33249 Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Reviewed-by: Thi N. Tran <thi@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33545 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/import/chips')
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C828
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.H16
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_quiesce_errors.xml26
3 files changed, 496 insertions, 374 deletions
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C b/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
index 40c9420b..7c1c0ae1 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER sbe Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,6 +36,12 @@
//
//--------------------------------------------------------------------------
+//*******************************************************************************************************
+//*******************************************************************************************************
+//TODO RTC Story 169882 - I NEED TO ADD IN ERROR HANDLING THAT WAS TAKEN OUT TO ALLOW THIS TO FIT
+//IN SBE!! THIS IS NOT READY FOR GA OR PRODUCTION YET BUT CAN BE USED FOR TESTING
+//*******************************************************************************************************
+//*******************************************************************************************************
//--------------------------------------------------------------------------
// Includes
@@ -46,15 +52,28 @@
#include <p9_misc_scom_addresses.H>
#include <p9_perv_scom_addresses_fld.H>
#include <p9_perv_scom_addresses.H>
-#include <p9_inject_local_xstop.H>
-#include <p9_thread_control.H>
+
+#ifndef CAPP_DD2
+ #include <p9_thread_control.H>
+ #include <p9_fbc_utils.H>
+ #include <p9_adu_setup.H>
+ #include <p9_adu_access.H>
+ #include <p9_adu_coherent_utils.H>
+#endif
extern "C" {
- //This is how many times each unit will try to do the quiesce if it has a wait for some condition to be set
- const uint32_t C_NUM_TRIES_QUIESCE_STATE = 5;
- //TODO RTC 160710
- const bool C_NX_DD2_READY = false;
+ //This is how many times each unit will try to do the quiesce if it has a wait for some cycles
+ const uint32_t C_NUM_TRIES_QUIESCE_STATE = 10000;
+ //These are the delays for the units that need them
+ const uint32_t C_CAPP_DELAY_NS = 168000000 / C_NUM_TRIES_QUIESCE_STATE; //168 ms
+ const uint32_t C_CAPP_DELAY_CYCLES = 336000000 / C_NUM_TRIES_QUIESCE_STATE; //2GHz * 168 ms
+ const uint32_t C_NPU_DELAY_NS = 150000 / C_NUM_TRIES_QUIESCE_STATE; //150 microseconds
+ const uint32_t C_NPU_DELAY_CYCLES = 300000 / C_NUM_TRIES_QUIESCE_STATE; //2GHz * 150 microseconds
+ const uint32_t C_DELAY_NS_396 = 396000000 / C_NUM_TRIES_QUIESCE_STATE; //396 ms -- Scott said this is too hard to answer
+ const uint32_t C_DELAY_CYCLES_396 = 792000000 / C_NUM_TRIES_QUIESCE_STATE; //2GHz * 396 ms
+ const uint32_t C_INTP_DELAY_NS = 10000 / C_NUM_TRIES_QUIESCE_STATE; //10 microseconds
+ const uint32_t C_INTP_DELAY_CYCLES = 20000 / C_NUM_TRIES_QUIESCE_STATE; //2GHz * 10 microseconds
//--------------------------------------------------------------------------
// HWP entry point
@@ -63,17 +82,13 @@ extern "C" {
fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
// SBE will check quiesce state for all units on the powerbus on its chip
- FAPI_TRY(p9_ec_eq_check_quiesce(i_target), "Error from p9_ec_eq_check_quiesce");
FAPI_TRY(p9_capp_check_quiesce(i_target), "Error from p9_capp_check_quiesce");
FAPI_TRY(p9_phb_check_quiesce(i_target), "Error from p9_phb_check_quiesce");
FAPI_TRY(p9_npu_check_quiesce(i_target), "Error from p9_npu_check_quiesce");
FAPI_TRY(p9_vas_check_quiesce(i_target), "Error from p9_vas_check_quiesce");
FAPI_TRY(p9_nx_check_quiesce(i_target), "Error from p9_nx_check_quiesce");
- //TODO it looks like the hca will not be in the plan RTC 160709
- //FAPI_TRY(p9_hca_check_quiesce(i_target), "Error from p9_hca_check_quiesce");
FAPI_TRY(p9_psihb_check_quiesce(i_target), "Error from p9_psihb_check_quiesce");
FAPI_TRY(p9_intp_check_quiesce(i_target), "Error from p9_intp_check_quiesce");
@@ -94,7 +109,6 @@ extern "C" {
}
}
- FAPI_DBG("Exiting...");
return saveError;
}
@@ -105,149 +119,110 @@ extern "C" {
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_ec_eq_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_capp_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
- fapi2::ReturnCode l_rc;
- const uint8_t C_ALL_THREADS = 0b1111;
-
- const uint64_t C_BLOCK_ALL_WKUP_EVENTS = 7;
- const uint64_t C_BLOCK_REG_WKUP_EVENTS = 6;
-
- fapi2::buffer<uint64_t> l_ras_status(0);
- fapi2::buffer<uint64_t> l_gpmmr_data(0);
- uint64_t l_state = 0x0ull;
- bool l_ras_is_in_stop = false;
- bool l_thread_warncheck = true;
-
// mark HWP entry
- FAPI_DBG("Entering ...\n");
- //Get all the cores on this proc chip
- auto l_core_targets = i_target.getChildren<fapi2::TARGET_TYPE_CORE>(fapi2::TARGET_STATE_FUNCTIONAL);
+ fapi2::buffer<uint64_t> l_data(0);
- //Block wake up on all cores
- l_gpmmr_data.setBit<C_BLOCK_ALL_WKUP_EVENTS>().setBit<C_BLOCK_REG_WKUP_EVENTS>();
+ //This part is actually used for the intp quiesce DD1 workaround but needs to be here because after this
+ //the fabric is finished
+#ifndef CAPP_DD2
+ uint64_t l_notify_page_addr = 0x0ull;
+ uint32_t l_numGranules;
+ p9_ADU_oper_flag l_adu_flag;
+ uint8_t l_write_data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ //Read the Interrupt Controller BAR to figure out the Notify Port page address
+ //Notify Port Page is the second page off the IC BAR
+ //bit 1 will tell whether we need to add a 4K offset (if bit 1 = '0') or 64K offset (if bit 1 = '1')
+ //Add this to the address (bits 8:48 of the IC BAR)
+ fapi2::getScom(i_target, PU_INT_CQ_IC_BAR, l_data);
+ l_notify_page_addr = (l_data & 0x00FFFFFFFFFF8000ull) + 0x1000;
+
+ if (l_data.getBit<1>() != 0)
+ {
+ l_notify_page_addr = l_notify_page_addr + 0xF000;
+ }
- for (auto& current_core : l_core_targets)
+ //---------------------
+ // Use syncs to mak sure no more requests are pending on the queues
+ //---------------------
+ //Trigger VC syncs
+ //write IPI trigger sync
+ l_adu_flag.setAutoIncrement(false);
+ l_adu_flag.setOperationType(p9_ADU_oper_flag::CACHE_INHIBIT);
+ l_adu_flag.setLockControl(true);
+ l_adu_flag.setOperFailCleanup(true);
+ l_adu_flag.setFastMode(false);
+ l_adu_flag.setItagMode(false);
+ l_adu_flag.setEccMode(false);
+ l_adu_flag.setEccItagOverrideMode(false);
+ l_adu_flag.setTransactionSize(static_cast<p9_ADU_oper_flag::Transaction_size_t>(0x8));
+ FAPI_TRY(p9_adu_setup(i_target, (l_notify_page_addr + 0xC00), false, l_adu_flag.setFlag(), l_numGranules));
+ FAPI_TRY(p9_adu_access(i_target, (l_notify_page_addr + 0xC00), false, l_adu_flag.setFlag(), true, true, l_write_data));
+ //write HW trigger sync
+ FAPI_TRY(p9_adu_setup(i_target, (l_notify_page_addr + 0xC80), false, l_adu_flag.setFlag(), l_numGranules));
+ FAPI_TRY(p9_adu_access(i_target, (l_notify_page_addr + 0xC80), false, l_adu_flag.setFlag(), true, true, l_write_data));
+ //write OS trigger sync
+ FAPI_TRY(p9_adu_setup(i_target, (l_notify_page_addr + 0xD00), false, l_adu_flag.setFlag(), l_numGranules));
+ FAPI_TRY(p9_adu_access(i_target, (l_notify_page_addr + 0xD00), false, l_adu_flag.setFlag(), true, true, l_write_data));
+ //write Hyp trigger sync
+ FAPI_TRY(p9_adu_setup(i_target, (l_notify_page_addr + 0xD80), false, l_adu_flag.setFlag(), l_numGranules));
+ FAPI_TRY(p9_adu_access(i_target, (l_notify_page_addr + 0xD80), false, l_adu_flag.setFlag(), true, true, l_write_data));
+ //Write Redist trigger sync
+ FAPI_TRY(p9_adu_setup(i_target, (l_notify_page_addr + 0xE00), false, l_adu_flag.setFlag(), l_numGranules));
+ FAPI_TRY(p9_adu_access(i_target, (l_notify_page_addr + 0xE00), false, l_adu_flag.setFlag(), true, true, l_write_data));
+#endif
+
+ fapi2::getScom(i_target, CAPP_FLUSHSHUE, l_data);
+
+ if (l_data != 0x0ull)
{
- //Stop the threads on each core
- FAPI_EXEC_HWP(l_rc, p9_thread_control, current_core, C_ALL_THREADS, PTC_CMD_STOP, l_thread_warncheck, l_ras_status,
- l_state);
- if (l_rc)
- {
- FAPI_ERR("Error from p9_thread_control in p9_sbe_check_quiesce");
- fapi2::current_err = l_rc;
- goto fapi_try_exit;
- }
+ // read the value of CAPP Error status and control register so we don't write over something
+ fapi2::getScom(i_target, CAPP_CAPP_ERR_STATUS_CONTROL, l_data);
- //Block wake up on each core
- FAPI_TRY(fapi2::putScom(current_core, C_PPM_GPMMR_SCOM1, l_gpmmr_data), "Error writing to GPMMR");
- }
+ // Write the Force Quiesce bit
+ l_data.setBit<CAPP_CAPP_ERR_STATUS_CONTROL_FORCE_QUIESCE>();
+ fapi2::putScom(i_target, CAPP_CAPP_ERR_STATUS_CONTROL, l_data);
- for (auto& current_core : l_core_targets)
- {
- // check for maint mode or STOP state in core RAS Status register (try 5 times), if not reached fail
- // All ECs should already be there per initial instruction stop
+ // Poll the Quiesce done bit
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_EXEC_HWP(l_rc, p9_thread_control, current_core, C_ALL_THREADS, PTC_CMD_QUERY, l_thread_warncheck, l_ras_status,
- l_state);
-
- if (l_rc)
- {
- FAPI_ERR("Error from p9_thread_control in p9_sbe_check_quiesce");
- fapi2::current_err = l_rc;
- goto fapi_try_exit;
- }
-
- l_ras_is_in_stop = (l_state && THREAD_STATE_MAINT) || (l_state && THREAD_STATE_QUIESCED);
+ fapi2::getScom(i_target, CAPP_CAPP_ERR_STATUS_CONTROL, l_data);
- if (l_ras_is_in_stop)
+ if (!l_data.getBit<CAPP_CAPP_ERR_STATUS_CONTROL_QUIESCE_DONE>())
{
break;
}
- }
-
- FAPI_ASSERT(l_ras_is_in_stop, fapi2::P9_RAS_STATUS_ERR().set_TARGET(current_core).set_RASSTATUS(l_ras_status),
- "Error with the RAS Status not being set as expected");
- }
-
- for (auto& current_core : l_core_targets)
- {
- // p9_inject_local_xstop.C
- // inject a local core checkstop on each core to prevent them from restarting
- FAPI_TRY(p9_inject_local_xstop(current_core), "Error in p9_inject_local_xstop");
- }
-
- fapi_try_exit:
- FAPI_DBG("Exiting...");
- return fapi2::current_err;
- }
-
- //---------------------------------------------------------------------------------
- // NOTE: description in header
- //---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_capp_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
- {
- // mark HWP entry
- FAPI_DBG("Entering ...\n");
-
- fapi2::buffer<uint64_t> l_capp_err_status_control_data(0);
- bool l_quiesce_achieved = false;
-
- // read the value of CAPP Error status and control register so we don't write over something
- FAPI_TRY(fapi2::getScom(i_target, CAPP_CAPP_ERR_STATUS_CONTROL, l_capp_err_status_control_data),
- "Error reading CAPP_ERR_STATUS_CONTROL register");
-
- // Write the Force Quiesce bit
- l_capp_err_status_control_data.setBit<CAPP_CAPP_ERR_STATUS_CONTROL_FORCE_QUIESCE>();
- FAPI_TRY(fapi2::putScom(i_target, CAPP_CAPP_ERR_STATUS_CONTROL, l_capp_err_status_control_data),
- "Error writing CAPP_ERR_STATUS_CONTROL register");
-
- // Poll the Quiesce done bit
- for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
- {
- FAPI_TRY(fapi2::getScom(i_target, CAPP_CAPP_ERR_STATUS_CONTROL, l_capp_err_status_control_data),
- "Error reading from VAS_MISC_NORTH_CTL register");
- if (!l_capp_err_status_control_data.getBit<CAPP_CAPP_ERR_STATUS_CONTROL_QUIESCE_DONE>())
- {
- l_quiesce_achieved = true;
- break;
+ fapi2::delay(C_CAPP_DELAY_NS, C_CAPP_DELAY_CYCLES);
}
- }
- FAPI_ASSERT(l_quiesce_achieved, fapi2::P9_CAPP_QUIESCE_TIMEOUT().set_TARGET(i_target).set_DATA(
- l_capp_err_status_control_data),
- "CAPP quiesce timed out");
+ FAPI_ASSERT(!l_data.getBit<CAPP_CAPP_ERR_STATUS_CONTROL_QUIESCE_DONE>(),
+ fapi2::P9_CAPP_QUIESCE_TIMEOUT().set_TARGET(i_target).set_DATA(l_data),
+ "CAPP quiesce timed out");
+ }
fapi_try_exit:
- FAPI_DBG("Exiting...");
return fapi2::current_err;
}
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_phb_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_phb_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
- fapi2::buffer<uint64_t> phb_hv_addr_reg_data(0x0888);
+ fapi2::buffer<uint64_t> l_data(0);
//We want to set bit 0 (the Quiesce DMA bit)
//This is the data that will be passed in to set the PHB Quiesce DMA register
- fapi2::buffer<uint64_t> phb_hv_data_reg_data(0x8000000000000000);
//The address of the PHB Quiesce DMA Register is 0x0888 (found in PHB spec)
uint8_t l_pci_id = 0;
uint64_t phb_absolute_address_array[3];
- uint8_t num_phbs = 0;
- uint64_t phb_addr_reg = 0;
- uint64_t phb_data_reg = 0;
+ uint32_t num_phbs = 0;
auto l_pci_chiplets_vec = i_target.getChildren<fapi2::TARGET_TYPE_PERV>(fapi2::TARGET_FILTER_ALL_PCI,
fapi2::TARGET_STATE_FUNCTIONAL);
@@ -255,7 +230,7 @@ extern "C" {
for (auto& l_pci_chiplet : l_pci_chiplets_vec)
{
//Get the PCI ID
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_pci_chiplet, l_pci_id), "Error getting the CHIP_UNIT_POS");
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_pci_chiplet, l_pci_id));
//There are a different number and different PHBs associated with each PCI ID
//PHB 0 is attached to PCI0
@@ -274,313 +249,338 @@ extern "C" {
}
else if (l_pci_id == 0xf)
{
- num_phbs = 3;
+ //Need to make sure that tc_pci2_iovalid(2) is 0b1 to access PHB5
+ fapi2::buffer<uint64_t> l_perv_pci2_cplt_conf1_data(0);
+ fapi2::getScom(i_target, PEC_2_CPLT_CONF1, l_perv_pci2_cplt_conf1_data);
+
+ if (l_perv_pci2_cplt_conf1_data.getBit<PEC_CPLT_CONF1_IOVALID_6D>())
+ {
+ num_phbs = 3;
+ phb_absolute_address_array[2] = PHB_5_PHB4_SCOM_HVIAR;
+ }
+ else
+ {
+ num_phbs = 2;
+ }
+
phb_absolute_address_array[0] = PHB_3_PHB4_SCOM_HVIAR;
phb_absolute_address_array[1] = PHB_4_PHB4_SCOM_HVIAR;
- phb_absolute_address_array[2] = PHB_5_PHB4_SCOM_HVIAR;
}
- for (uint8_t i = 0; i < num_phbs; i++)
+ for (uint32_t i = 0; i < num_phbs; i++)
{
- phb_addr_reg = phb_absolute_address_array[i];
- phb_data_reg = phb_absolute_address_array[i] + 1;
//Clear contents of PHB HV Indirect Address Register
- phb_hv_addr_reg_data.flush<0>();
- FAPI_TRY(fapi2::putScom(i_target, phb_addr_reg, phb_hv_addr_reg_data),
- "Error clearing PHB HV Indirect Address Register");
+ l_data.flush<0>();
+ fapi2::putScom(i_target, phb_absolute_address_array[i], l_data);
//Setup the PHB HV registers for the write
- phb_hv_addr_reg_data.insertFromRight<PHB_HV_IND_ADDR_START_BIT, PHB_HV_IND_ADDR_LEN>(0x888);
- phb_hv_addr_reg_data.setBit<PHB_HV_IND_ADDR_VALID_BIT>();
- FAPI_TRY(fapi2::putScom(i_target, phb_addr_reg, phb_hv_addr_reg_data),
- "Error writing PHB HV Indirect Address Register");
+ l_data.insertFromRight<PHB_HV_IND_ADDR_START_BIT, PHB_HV_IND_ADDR_LEN>(0x888);
+ l_data.setBit<PHB_HV_IND_ADDR_VALID_BIT>();
+ fapi2::putScom(i_target, phb_absolute_address_array[i], l_data);
//Setup PHB HV Indirect for write access
- FAPI_TRY(fapi2::putScom(i_target, phb_data_reg, phb_hv_data_reg_data),
- "Error writing PHB HV Indirect Data Register");
+ l_data.flush<0>().insertFromRight<0, 63>(0x8000000000000000);
+ fapi2::putScom(i_target, (phb_absolute_address_array[i] + 1), l_data);
//Clear contents of PHB HV Indirect Address Register
- phb_hv_addr_reg_data.flush<0>();
- FAPI_TRY(fapi2::putScom(i_target, phb_addr_reg, phb_hv_addr_reg_data),
- "Error clearing PHB HV Indirect Address Register");
+ l_data.flush<0>();
+ fapi2::putScom(i_target, phb_absolute_address_array[i], l_data);
}
}
fapi_try_exit:
- FAPI_DBG("Exiting...");
return fapi2::current_err;
}
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_npu_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_npu_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
const uint32_t c_fence_status_reg_size = 6;
+
+ fapi2::buffer<uint64_t> l_data(0);
+ const uint32_t CQ_fence_status_regs[c_fence_status_reg_size] = {0x00090500, 0x000B0500, 0x00190500, 0x001B0500, 0x00290500, 0x002B0500};
+ const uint32_t c_config_size = 6;
+#ifndef NPU_DD2
const uint32_t c_GPU_Memory_BARs_size = 12;
const uint32_t c_memory_bars_size = 36;
-
- fapi2::buffer<uint64_t> l_ntl_misc_config_1_reg_data(0);
- fapi2::buffer<uint64_t> l_npu_indirect_address_reg_data(0);
- fapi2::buffer<uint64_t> l_npu_indirect_data_reg_data[6];
- fapi2::buffer<uint64_t> l_npu_fence_state_reg_data(0);
- fapi2::buffer<uint64_t> l_memory_bar_data(0);
- uint64_t CQ_fence_status_regs[c_fence_status_reg_size] = {0x00090500, 0x000B0500, 0x00190500, 0x001B0500, 0x00290500, 0x002B0500};
- uint64_t l_GPU_Memory_BARs[c_GPU_Memory_BARs_size] = {PU_NPU0_SM0_GPU_BAR, PU_NPU0_SM1_GPU_BAR, PU_NPU0_SM2_GPU_BAR, PU_NPU0_SM3_GPU_BAR, PU_NPU1_SM0_GPU_BAR, PU_NPU1_SM1_GPU_BAR, PU_NPU1_SM2_GPU_BAR, PU_NPU1_SM3_GPU_BAR, PU_NPU2_SM0_GPU_BAR, PU_NPU2_SM1_GPU_BAR, PU_NPU2_SM2_GPU_BAR, PU_NPU2_SM3_GPU_BAR};
- uint64_t l_memory_bars[c_memory_bars_size] = {PU_NPU0_SM0_NDT0_BAR, PU_NPU0_SM1_NDT0_BAR, PU_NPU0_SM2_NDT0_BAR, PU_NPU0_SM3_NDT0_BAR, PU_NPU1_SM0_NDT0_BAR, PU_NPU1_SM1_NDT0_BAR, PU_NPU1_SM2_NDT0_BAR, PU_NPU1_SM3_NDT0_BAR, PU_NPU2_SM0_NDT0_BAR, PU_NPU2_SM1_NDT0_BAR, PU_NPU2_SM2_NDT0_BAR, PU_NPU2_SM3_NDT0_BAR, PU_NPU0_SM0_NDT1_BAR, PU_NPU0_SM1_NDT1_BAR, PU_NPU0_SM2_NDT1_BAR, PU_NPU0_SM3_NDT1_BAR, PU_NPU1_SM0_NDT1_BAR, PU_NPU1_SM1_NDT1_BAR, PU_NPU1_SM2_NDT1_BAR, PU_NPU1_SM3_NDT1_BAR, PU_NPU2_SM0_NDT1_BAR, PU_NPU2_SM1_NDT1_BAR, PU_NPU2_SM2_NDT1_BAR, PU_NPU2_SM3_NDT1_BAR, PU_NPU0_SM0_PHY_BAR, PU_NPU0_SM1_PHY_BAR, PU_NPU0_SM2_PHY_BAR, PU_NPU0_SM3_PHY_BAR, PU_NPU1_SM0_PHY_BAR, PU_NPU1_SM1_PHY_BAR, PU_NPU1_SM2_PHY_BAR, PU_NPU1_SM3_PHY_BAR, PU_NPU2_SM0_PHY_BAR, PU_NPU2_SM1_PHY_BAR, PU_NPU2_SM2_PHY_BAR, PU_NPU2_SM3_PHY_BAR };
- bool l_NTL_in_reset_state[c_fence_status_reg_size] = {false, false, false, false, false, false};
- bool l_all_NTL_in_reset_state = false;
+ const uint64_t l_GPU_Memory_BARs[c_GPU_Memory_BARs_size] = {PU_NPU0_SM0_GPU_BAR, PU_NPU0_SM1_GPU_BAR, PU_NPU0_SM2_GPU_BAR, PU_NPU0_SM3_GPU_BAR, PU_NPU1_SM0_GPU_BAR, PU_NPU1_SM1_GPU_BAR, PU_NPU1_SM2_GPU_BAR, PU_NPU1_SM3_GPU_BAR, PU_NPU2_SM0_GPU_BAR, PU_NPU2_SM1_GPU_BAR, PU_NPU2_SM2_GPU_BAR, PU_NPU2_SM3_GPU_BAR};
+ const uint64_t l_memory_bars[c_memory_bars_size] = {PU_NPU0_SM0_NDT0_BAR, PU_NPU0_SM1_NDT0_BAR, PU_NPU0_SM2_NDT0_BAR, PU_NPU0_SM3_NDT0_BAR, PU_NPU1_SM0_NDT0_BAR, PU_NPU1_SM1_NDT0_BAR, PU_NPU1_SM2_NDT0_BAR, PU_NPU1_SM3_NDT0_BAR, PU_NPU2_SM0_NDT0_BAR, PU_NPU2_SM1_NDT0_BAR, PU_NPU2_SM2_NDT0_BAR, PU_NPU2_SM3_NDT0_BAR, PU_NPU0_SM0_NDT1_BAR, PU_NPU0_SM1_NDT1_BAR, PU_NPU0_SM2_NDT1_BAR, PU_NPU0_SM3_NDT1_BAR, PU_NPU1_SM0_NDT1_BAR, PU_NPU1_SM1_NDT1_BAR, PU_NPU1_SM2_NDT1_BAR, PU_NPU1_SM3_NDT1_BAR, PU_NPU2_SM0_NDT1_BAR, PU_NPU2_SM1_NDT1_BAR, PU_NPU2_SM2_NDT1_BAR, PU_NPU2_SM3_NDT1_BAR, PU_NPU0_SM0_PHY_BAR, PU_NPU0_SM1_PHY_BAR, PU_NPU0_SM2_PHY_BAR, PU_NPU0_SM3_PHY_BAR, PU_NPU1_SM0_PHY_BAR, PU_NPU1_SM1_PHY_BAR, PU_NPU1_SM2_PHY_BAR, PU_NPU1_SM3_PHY_BAR, PU_NPU2_SM0_PHY_BAR, PU_NPU2_SM1_PHY_BAR, PU_NPU2_SM2_PHY_BAR, PU_NPU2_SM3_PHY_BAR };
+ const uint64_t l_NTL_config_addrs[c_config_size] = {NV_0_CONFIG1, NV_1_CONFIG1, NV_2_CONFIG1, NV_3_CONFIG1, PU_NPU2_NTL0_CONFIG1, PU_NPU2_NTL1_CONFIG1};
+#else
+ const uint32_t c_GPU_Memory_BARs_DD2_size = 24;
+ const uint32_t c_memory_bars_size_dd2 = 48;
+ const uint32_t l_GPU_Memory_BARs_DD2[c_GPU_Memory_BARs_DD2_size] = {0x5011004, 0x5011034, 0x5011064, 0x5011094, 0x5011204, 0x5011234, 0x5011264, 0x5011294, 0x5011404, 0x5011434, 0x5011464, 0x5011494, 0x5011005, 0x5011035, 0x5011065, 0x5011095, 0x5011205, 0x5011235, 0x5011265, 0x5011295, 0x5011405, 0x5011435, 0x5011465, 0x5011495};
+ const uint32_t l_memory_bars_dd2[c_memory_bars_size_dd2] = {0x501100D, 0x501103D, 0x501106D, 0x501109D, 0x501100E, 0x501103E, 0x501106E, 0x501109E, 0x501120D, 0x501123D, 0x501126D, 0x501129D, 0x501120E, 0x501123E, 0x501126E, 0x501129E, 0x501140D, 0x501143D, 0x501146D, 0x501149D, 0x501140E, 0x501143E, 0x501146E, 0x501149E, 0x5011406, 0x5011436, 0x5011466, 0x5011496, 0x5011206, 0x5011236, 0x5011266, 0x5011296, 0x5011007, 0x5011037, 0x5011067, 0x5011097, 0x5011207, 0x5011237, 0x5011267, 0x5011297, 0x5011407, 0x5011437, 0x5011467, 0x5011497, 0x5011006, 0x5011036, 0x5011366, 0x5011396};
+ const uint32_t l_NTL_config_addrs_DD2[c_config_size] = {0x5011128, 0x5011148, 0x5011328, 0x5011348, 0x5011528, 0x5011548}
+#endif
+ uint32_t l_GPU_Memory_BARs_size_for_loop = 0;
+ uint32_t l_memory_bars_size_for_loop = 0;
+
+
+#ifndef NPU_DD2
+ l_GPU_Memory_BARs_size_for_loop = c_GPU_Memory_BARs_size;
+ l_memory_bars_size_for_loop = c_memory_bars_size;
+#else
+ l_GPU_Memory_BARs_size_for_loop = c_GPU_Memory_BARs_DD2_size;
+ l_memory_bars_size_for_loop = c_memory_bars_size_dd2;
+#endif
// 1) Place all six of the NTLs into Reset State
// Set bits 8:9 in the NTL Misc Config 1 registers to place NTLs in Reset state
- l_ntl_misc_config_1_reg_data.insertFromRight<NV_CONFIG1_NTL_RESET, NV_CONFIG1_NTL_RESET_LEN>(0x3);
- FAPI_TRY(fapi2::putScom(i_target, NV_0_CONFIG1, l_ntl_misc_config_1_reg_data),
- "Error writing to NV 0 Config1 register");
- FAPI_TRY(fapi2::putScom(i_target, NV_1_CONFIG1, l_ntl_misc_config_1_reg_data),
- "Error writing to NV 1 Config1 register");
- FAPI_TRY(fapi2::putScom(i_target, NV_2_CONFIG1, l_ntl_misc_config_1_reg_data),
- "Error writing to NV 2 Config1 register");
- FAPI_TRY(fapi2::putScom(i_target, NV_3_CONFIG1, l_ntl_misc_config_1_reg_data),
- "Error writing to NV 3 Config1 register");
- FAPI_TRY(fapi2::putScom(i_target, PU_NPU2_NTL0_CONFIG1, l_ntl_misc_config_1_reg_data),
- "Error writing to NPU2 NTL0 Config1 register");
- FAPI_TRY(fapi2::putScom(i_target, PU_NPU2_NTL1_CONFIG1, l_ntl_misc_config_1_reg_data),
- "Error writing to NPU2 NTL1 Config1 register");
+ for (uint32_t i = 0; i < c_config_size; i++)
+ {
+#ifndef NPU_DD2
+ fapi2::getScom(i_target, l_NTL_config_addrs[i], l_data);
+#else
+ fapi2::getScom(i_target, l_NTL_config_addrs_DD2[i], l_data);
+#endif
+ l_data.insertFromRight<NV_CONFIG1_NTL_RESET, NV_CONFIG1_NTL_RESET_LEN>(0x3);
+#ifndef NPU_DD2
+ fapi2::putScom(i_target, l_NTL_config_addrs[i], l_data);
+#else
+ fapi2::putScom(i_target, l_NTL_config_addrs_DD2[i], l_data);
+#endif
+ }
//Poll the CQ Fence Status Registers util "Value" is detected to verify that NTLs are in Reset State
for (uint32_t i = 0; i < c_fence_status_reg_size; i++)
{
- for (uint32_t j = 0; j < C_NUM_TRIES_QUIESCE_STATE; j ++)
+ for (uint32_t j = 0; j < CAPP_CAPP_ERR_STATUS_CONTROL_QUIESCE_DONE; j++)
{
- l_npu_indirect_address_reg_data.flush<0>().insertFromRight<PU_NPU_CTL_DA_ADDR_MISC, PU_NPU_CTL_DA_ADDR_MISC_LEN>
+ l_data.flush<0>().insertFromRight<PU_NPU_CTL_DA_ADDR_MISC, PU_NPU_CTL_DA_ADDR_MISC_LEN>
(CQ_fence_status_regs[i]);
- FAPI_TRY(fapi2::putScom(i_target, PU_NPU_CTL_DA_ADDR, l_npu_indirect_address_reg_data),
- "Error writing to NPU Indirect Address register");
- FAPI_TRY(fapi2::getScom(i_target, PU_NPU_CTL_DA_DATA, l_npu_indirect_data_reg_data[i]),
- "Error reading from NPU Indirect Data register");
- if (l_npu_indirect_data_reg_data[i].getBit<0>() && l_npu_indirect_data_reg_data[i].getBit<1>())
+#ifndef NPU_DD2
+ fapi2::putScom(i_target, PU_NPU_CTL_DA_ADDR, l_data);
+ fapi2::getScom(i_target, PU_NPU_CTL_DA_DATA, l_data);
+#else
+ fapi2::putScom(i_target, 0x501168E, l_data);
+ fapi2::getScom(i_target, 0x501168F, l_data);
+#endif
+
+ if (l_data.getBit<0>() && l_data.getBit<1>())
{
- l_NTL_in_reset_state[i] = true;
break;
}
+
+ fapi2::delay(C_NPU_DELAY_NS, C_NPU_DELAY_CYCLES);
}
- }
- l_all_NTL_in_reset_state = l_NTL_in_reset_state[0] && l_NTL_in_reset_state[1] && l_NTL_in_reset_state[2]
- && l_NTL_in_reset_state[3] && l_NTL_in_reset_state[4] && l_NTL_in_reset_state[5];
- FAPI_ASSERT(l_all_NTL_in_reset_state,
- fapi2::P9_NTL_NOT_IN_RESET().set_TARGET(i_target).set_NTL_DATA0(l_npu_indirect_data_reg_data[0]).set_NTL_DATA1(
- l_npu_indirect_data_reg_data[1]).set_NTL_DATA2(l_npu_indirect_data_reg_data[2]).set_NTL_DATA3(
- l_npu_indirect_data_reg_data[3]).set_NTL_DATA4(l_npu_indirect_data_reg_data[4]).set_NTL_DATA5(
- l_npu_indirect_data_reg_data[5]), "One or more of the NTLS are not in the reset state");
+ FAPI_ASSERT((l_data.getBit<0>()
+ && l_data.getBit<1>()), fapi2::P9_NTL_NOT_IN_RESET().set_TARGET(i_target).set_NTL_ADDR(
+ CQ_fence_status_regs[i]).set_NTL_DATA(l_data), "One of the NTLS are not in the reset state");
+ }
- // 2) Place allNV-Link Bricks into Fence State
+ // 2) Place all NV-Link Bricks into Fence State
// Set bits 0:5 in the NPU Fence State register to place all bricks into Fence State
- l_npu_fence_state_reg_data.setBit<PU_NPU_CTL_FENCE_STATE_BRK0>().setBit<PU_NPU_CTL_FENCE_STATE_BRK1>().setBit<PU_NPU_CTL_FENCE_STATE_BRK2>().setBit<PU_NPU_CTL_FENCE_STATE_BRK3>().setBit<PU_NPU_CTL_FENCE_STATE_BRK4>().setBit<PU_NPU_CTL_FENCE_STATE_BRK5>();
- FAPI_TRY(fapi2::putScom(i_target, PU_NPU_CTL_FENCE_STATE, l_npu_fence_state_reg_data),
- "Error writing to the NPU Fence State Register");
+ l_data.setBit<PU_NPU_CTL_FENCE_STATE_BRK0>().setBit<PU_NPU_CTL_FENCE_STATE_BRK1>().setBit<PU_NPU_CTL_FENCE_STATE_BRK2>().setBit<PU_NPU_CTL_FENCE_STATE_BRK3>().setBit<PU_NPU_CTL_FENCE_STATE_BRK4>().setBit<PU_NPU_CTL_FENCE_STATE_BRK5>();
+
+#ifndef NPU_DD2
+ fapi2::putScom(i_target, PU_NPU_CTL_FENCE_STATE, l_data);
+#else
+ fapi2::buffer<uint64_t> l_npu_interrupt_reg_data(0);
+ fapi2::putScom(i_target, 0x5011696, l_data);
+ //Write bits 0:22 of the NPU Interrupt Request register to eliminate any interrupt requests that occurred between steps 1 and 2.
+ fapi2::putScom(i_target, 0x5011697, l_npu_interrupt_reg_data);
+#endif
// 3) Disable all NPU BAR registers
// Reset bits 0 and 32 in the GPU-Memory BARs to stop NPU from responding to accesses to GPU memory
- l_memory_bar_data.clearBit<PU_NPU0_SM0_GPU_BAR_CONFIG_GPU0_ENABLE>().clearBit<PU_NPU0_SM0_GPU_BAR_CONFIG_GPU1_ENABLE>();
- for (uint32_t i = 0; i < c_GPU_Memory_BARs_size; i++)
+ for (uint32_t i = 0; i < l_GPU_Memory_BARs_size_for_loop; i++)
{
- FAPI_TRY(fapi2::putScom(i_target, l_GPU_Memory_BARs[i], l_memory_bar_data),
- "Error writing to NPU0 SM0 GPU BAR register");
+ l_data.flush<0>().clearBit<PU_NPU0_SM0_GPU_BAR_CONFIG_GPU0_ENABLE>().clearBit<PU_NPU0_SM0_GPU_BAR_CONFIG_GPU1_ENABLE>();
+#ifndef NPU_DD2
+ fapi2::putScom(i_target, l_GPU_Memory_BARs[i], l_data);
+#else
+ fapi2::putScom(i_target, l_GPU_Memory_BARs_DD2[i], l_data);
+#endif
}
// Reset bit 0 in the NTL0/NDL0 Memory BARs and NTL1/NDL1 Memory BARs to stop NPU from responding to accesses to NTL/NDL registers
// Reset bit 0 in PHY0/PHY1/NPU MMIO BAR for stack 0 and stack 1 to stop NPU from responding to PHY register accesses
// Reset bit 0 in PHY0/PHY1/NPU MMIO BARs in stack 2 to stop NPU from responding to NPU MMIO register accesses
- l_memory_bar_data.flush<0>().clearBit<PU_NPU0_SM0_NDT0_BAR_CONFIG_ENABLE>();
-
- for (uint32_t i = 0; i < c_memory_bars_size; i++)
+ for (uint32_t i = 0; i < l_memory_bars_size_for_loop; i++)
{
- FAPI_TRY(fapi2::putScom(i_target, l_memory_bars[i], l_memory_bar_data), "Error writing to NPU0 SM0 NDT0 BAR register");
+ l_data.flush<0>().clearBit<PU_NPU0_SM0_NDT0_BAR_CONFIG_ENABLE>();
+#ifndef NPU_DD2
+ fapi2::putScom(i_target, l_memory_bars[i], l_data);
+#else
+ fapi2::putScom(i_target, l_memory_bars_dd2[i], l_data);
+#endif
}
fapi_try_exit:
- FAPI_DBG("Exiting...");
return fapi2::current_err;
}
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_vas_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_vas_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
fapi2::buffer<uint64_t> l_vas_north_misc_ctl_data(0);
fapi2::buffer<uint64_t> l_vas_south_misc_ctl_data(0);
- bool l_quiesce_achieved = false;
// VAS needs to be quiesced before NX
// Read the VAS Misc status and North control register so we don't write over anything
- FAPI_TRY(fapi2::getScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data),
- "Error reading from VAS_MISC_NORTH_CTL register");
+ fapi2::getScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data);
// Set the 'Quiesce Requested' bit in the VAS Miscellaneous Status and North Control Register to a 1. This will prevent VAS from accepting new paste or write monitor operations
l_vas_north_misc_ctl_data.setBit<PU_VAS_MISCCTL_MISC_CTL_QUIESCE_REQUEST>();
- FAPI_TRY(fapi2::putScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data),
- "Error writing to VAS_MISC_NORTH_CTL register");
+ fapi2::putScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data);
//Check that VAS has quiesced. This is accomplished by reading two status registers. The "RG is Idle' bit in the VAS Miscellaneous Status and North Control Register as well as the 'EG is Idle', 'CQ is Idle' and 'WC is Idle' bit sin the VAS Miscellaneous Status and South Control Register must all be set to one to indicate that VAS has gone idle.
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
// Read VAS Misc status and North control register to ensure 'RG is idle' and 'EG is idle' bits are both set -
- FAPI_TRY(fapi2::getScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data),
- "Error reading from VAS_MISC_NORTH_CTL register");
+ fapi2::getScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data);
// Read VAS Misc status and South control register to ensure 'WC is idle' and 'CQ is idle' bits are both set -
- FAPI_TRY(fapi2::getScom(i_target, PU_VAS_SOUTHCTL, l_vas_south_misc_ctl_data),
- "Error reading from VAS_MISC_SOUTH_CTL register");
+ fapi2::getScom(i_target, PU_VAS_SOUTHCTL, l_vas_south_misc_ctl_data);
if (l_vas_north_misc_ctl_data.getBit<PU_VAS_MISCCTL_MISC_CTL_RG_IS_IDLE>()
&& l_vas_south_misc_ctl_data.getBit<PU_VAS_SOUTHCTL_SOUTH_CTL_WC_IDLE_BIT>()
&& l_vas_south_misc_ctl_data.getBit<PU_VAS_SOUTHCTL_SOUTH_CTL_CQ_IDLE_BIT>()
&& l_vas_south_misc_ctl_data.getBit<PU_VAS_SOUTHCTL_SOUTH_CTL_EG_IDLE_BIT>())
{
- l_quiesce_achieved = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
//In order to prevent additional FIFO entries from getting posted to the NX receive FIFOs while trying to quiesce NX, software may wish to close all windows to prevent users from continuing to try to access the accelerators. Software may close all windows by writing the Open/Enable bit to a zero in the Window Control Register<n>. This step is optional, but should be done as part of an orderly shut down of a user's access.
//Software may also choose to deallocate any pages that partitions (or users) have mapped to VAS' MMIO space. In a general use case, a partition (or user) will have pages that map to VAS' MMIO space to allow the partition to return credits via the Local Receive Window Credit Adder Register <m>. In order to stop MMIO traffic, these pages should be unmapped. In a NX only usage model, this step can be ignored as long as the Quiesce NX procedures are followed.
- FAPI_ASSERT(l_quiesce_achieved, fapi2::P9_VAS_QUIESCE_TIMEOUT().set_TARGET(i_target).set_NORTHDATA(
+ FAPI_ASSERT((l_vas_north_misc_ctl_data.getBit<PU_VAS_MISCCTL_MISC_CTL_RG_IS_IDLE>()
+ && l_vas_south_misc_ctl_data.getBit<PU_VAS_SOUTHCTL_SOUTH_CTL_WC_IDLE_BIT>()
+ && l_vas_south_misc_ctl_data.getBit<PU_VAS_SOUTHCTL_SOUTH_CTL_CQ_IDLE_BIT>()
+ && l_vas_south_misc_ctl_data.getBit<PU_VAS_SOUTHCTL_SOUTH_CTL_EG_IDLE_BIT>()),
+ fapi2::P9_VAS_QUIESCE_TIMEOUT().set_TARGET(i_target).set_NORTHDATA(
l_vas_north_misc_ctl_data).set_SOUTHDATA(l_vas_south_misc_ctl_data),
"VAS quiesce timed out");
// Write Invalidate CAM location field of North register (optional)
l_vas_north_misc_ctl_data.setBit<PU_VAS_MISCCTL_MISC_CTL_INVALIDATE_CAM_ALL>();
- FAPI_TRY(fapi2::putScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data),
- "Error writing to VAS_MISC_NORTH_CTL register");
+ fapi2::putScom(i_target, PU_VAS_MISCCTL, l_vas_north_misc_ctl_data);
fapi_try_exit:
- FAPI_DBG("Exiting...");
return fapi2::current_err;
}
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_nx_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_nx_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
fapi2::buffer<uint64_t> l_dma_status_reg_data(0);
- fapi2::buffer<uint64_t> l_pb_err_rpt0_data(0);
- fapi2::buffer<uint64_t> l_umac_status_ctrl_data(0);
- fapi2::buffer<uint64_t> l_crb_kill_req_data(0);
- fapi2::buffer<uint64_t> l_erat_status_control_data(0);
- bool l_quiesce_achieved = false;
- bool l_go_to_next_nx_step = false;
+ fapi2::buffer<uint64_t> l_data(0);
//If (DMA Status Register[HMI Ative])
- FAPI_TRY(fapi2::getScom(i_target, PU_SU_STATUS, l_dma_status_reg_data), "Error reading from DMA Status Register");
+ fapi2::getScom(i_target, PU_SU_STATUS, l_dma_status_reg_data);
- if(l_dma_status_reg_data.getBit<PU_SU_STATUS_HMI_ACTIVE>())
+ //If HMI has een signaled, NX PBI is frozen and read machines may be stuck active. The quiesce may either be abandoned or write machines idle status can be polled in lieu of the quiesce procedure. The latter is selected here.
+ if (l_dma_status_reg_data.getBit<PU_SU_STATUS_HMI_ACTIVE>())
{
//then while (!PowerBus Interface Error Report 0 Register[PBI Write Idle])
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_NX_PB_ERR_RPT_0, l_pb_err_rpt0_data),
- "Error reading from PowerBus Interface Error Report");
+ fapi2::getScom(i_target, PU_NX_PB_ERR_RPT_0, l_data);
- if (l_pb_err_rpt0_data.getBit<PU_NX_PB_ERR_RPT_0_PBI_WRITE_IDLE>())
+ if (l_data.getBit<PU_NX_PB_ERR_RPT_0_PBI_WRITE_IDLE>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_NX_PBI_WRITE_IDLE_TIMEOUT().set_TARGET(i_target).set_DATA(
- l_pb_err_rpt0_data), "PBI Write Idle never happened");
- l_go_to_next_nx_step = false;
+ FAPI_ASSERT((l_data.getBit<PU_NX_PB_ERR_RPT_0_PBI_WRITE_IDLE>()),
+ fapi2::P9_NX_PBI_WRITE_IDLE_TIMEOUT().set_TARGET(i_target).set_DATA(
+ l_data), "PBI Write Idle never happened");
+ }
+ if(!l_dma_status_reg_data.getBit<PU_SU_STATUS_HMI_ACTIVE>() || l_data.getBit<PU_NX_PB_ERR_RPT_0_PBI_WRITE_IDLE>())
+ {
//Any CRB kill must be complete before issuing the following sequence
- FAPI_TRY(fapi2::getScom(i_target, PU_SU_CRB_KILL_REQ, l_crb_kill_req_data), "Error reading CRB Kill Request Register");
+ fapi2::getScom(i_target, PU_SU_CRB_KILL_REQ, l_data);
//if (CRB Kill Request Configuration Register[Kill Enable])
- if (l_crb_kill_req_data.getBit<PU_SU_CRB_KILL_REQ_ENABLE>())
+ if (l_data.getBit<PU_SU_CRB_KILL_REQ_ENABLE>())
{
//while(!CRB Kill Request Configuration Register[Kill Done]){}
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_SU_CRB_KILL_REQ, l_crb_kill_req_data), "Error reading CRB Kill Request Register");
+ fapi2::getScom(i_target, PU_SU_CRB_KILL_REQ, l_data);
- if (l_crb_kill_req_data.getBit<PU_SU_CRB_KILL_REQ_DONE>())
+ if (l_data.getBit<PU_SU_CRB_KILL_REQ_DONE>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_NX_CRB_KILL_DONE_TIMEOUT().set_TARGET(i_target).set_DATA(
- l_crb_kill_req_data), "CRB kills were not complete");
+ FAPI_ASSERT(l_data.getBit<PU_SU_CRB_KILL_REQ_DONE>(),
+ fapi2::P9_NX_CRB_KILL_DONE_TIMEOUT().set_TARGET(i_target).set_DATA(
+ l_data), "CRB kills were not complete");
}
- l_go_to_next_nx_step = false;
-
//Stop UMAC from fetching new CRBs
- FAPI_TRY(fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error reading from UMAC_STATUS_CONTROL_REG");
+ fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
//clear_reg(UMAC Status and Control Register[CRB Read Enable])
- l_umac_status_ctrl_data.clearBit<PU_UMAC_STATUS_CONTROL_CRB_READS_ENBL>();
- FAPI_TRY(fapi2::putScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error writing to UMAC_STATUS_CONTROL_REG");
+ l_data.clearBit<PU_UMAC_STATUS_CONTROL_CRB_READS_ENBL>();
+ fapi2::putScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
//while(!UMAC Status and Control Register[CRB Read Halted]){}
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error reading from UMAC_STATUS_CONTROL_REG");
+ fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
- if (l_umac_status_ctrl_data.getBit<PU_UMAC_STATUS_CONTROL_CRB_READS_HALTED>())
+ if (l_data.getBit<PU_UMAC_STATUS_CONTROL_CRB_READS_HALTED>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_NX_STOP_UMAC_FETCHING_NEW_CRBS_TIMEOUT().set_TARGET(i_target).set_DATA(
- l_umac_status_ctrl_data), "UMAC was not stopped from fetching new CRBs");
- l_go_to_next_nx_step = false;
+ FAPI_ASSERT(l_data.getBit<PU_UMAC_STATUS_CONTROL_CRB_READS_HALTED>(),
+ fapi2::P9_NX_STOP_UMAC_FETCHING_NEW_CRBS_TIMEOUT().set_TARGET(i_target).set_DATA(
+ l_data), "UMAC was not stopped from fetching new CRBs");
//Wait for UMAC dispatch slots to drain of CRBs
//UMAC can still have CRBs queued in receive FIFOs
//while(!UMAC Status and Control Register[UMAC Quiesced]){}
- for(uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
+ for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error reading from UMAC_STATUS_CONTROL_REG");
+ fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
- if (l_umac_status_ctrl_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCED>())
+ if (l_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCED>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_NX_UMAC_DISPATCH_SLOTS_TO_DRAIN_CRBS_TIMEOUT().set_TARGET(
+
+ FAPI_ASSERT(l_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCED>(),
+ fapi2::P9_NX_UMAC_DISPATCH_SLOTS_TO_DRAIN_CRBS_TIMEOUT().set_TARGET(
i_target).set_DATA(
- l_umac_status_ctrl_data), "UMAC was not done dispatching slots to drain of CRBs");
- l_go_to_next_nx_step = false;
+ l_data), "UMAC was not done dispatching slots to drain of CRBs");
//Wait for DMA channels to drain
//while(DMA Status Register[DMA Channel 0:4 Idle] != 5b1_1111){}
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_SU_STATUS, l_dma_status_reg_data), "Error reading from DMA Status Register");
+ fapi2::getScom(i_target, PU_SU_STATUS, l_dma_status_reg_data);
if (l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH0_IDLE>()
&& l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH1_IDLE>()
@@ -588,202 +588,326 @@ extern "C" {
&& l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH3_IDLE>()
&& l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH4_IDLE>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_WAIT_FOR_DMA_CHANNELS_TO_DRAIN_TIMEOUT().set_TARGET(i_target).set_DATA(
+ FAPI_ASSERT((l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH0_IDLE>()
+ && l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH1_IDLE>()
+ && l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH2_IDLE>()
+ && l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH3_IDLE>()
+ && l_dma_status_reg_data.getBit<PU_SU_STATUS_DMA_CH4_IDLE>()),
+ fapi2::P9_WAIT_FOR_DMA_CHANNELS_TO_DRAIN_TIMEOUT().set_TARGET(i_target).set_DATA(
l_dma_status_reg_data), "DMA channels were not drained");
- l_go_to_next_nx_step = false;
//Wait for ERAT to be idle. Should be trivially idle because of the above.
//while(!ERAT Status and Control Register[ERAT idle]){}
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_ERAT_STATUS_CONTROL, l_erat_status_control_data),
- "Error reading from the ERAT Status and Control Register");
+ fapi2::getScom(i_target, PU_ERAT_STATUS_CONTROL, l_data);
- if (l_erat_status_control_data.getBit<PU_ERAT_STATUS_CONTROL_IDLE>())
+ if (l_data.getBit<PU_ERAT_STATUS_CONTROL_IDLE>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_WAIT_FOR_ERAT_IDLE().set_TARGET(i_target).set_DATA(
- l_erat_status_control_data),
+ FAPI_ASSERT(l_data.getBit<PU_ERAT_STATUS_CONTROL_IDLE>(), fapi2::P9_WAIT_FOR_ERAT_IDLE().set_TARGET(i_target).set_DATA(
+ l_data),
"ERAT was not idle");
- l_go_to_next_nx_step = false;
//Wait for PBI master machines to be idle
//while(!DMA Status Register[PBI Idle]){}
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_SU_STATUS, l_dma_status_reg_data), "Error reading from DMA Status Register");
+ fapi2::getScom(i_target, PU_SU_STATUS, l_dma_status_reg_data);
if (l_dma_status_reg_data.getBit<PU_SU_STATUS_PBI_IDLE>())
{
- l_go_to_next_nx_step = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_go_to_next_nx_step, fapi2::P9_PBI_MASTER_MACHINES_IDLE_TIMEOUT().set_TARGET(i_target).set_DATA(
+ FAPI_ASSERT(l_dma_status_reg_data.getBit<PU_SU_STATUS_PBI_IDLE>(),
+ fapi2::P9_PBI_MASTER_MACHINES_IDLE_TIMEOUT().set_TARGET(i_target).set_DATA(
l_dma_status_reg_data), "PBI Master Machines are not idle");
- l_go_to_next_nx_step = false;
}
//If this procedure is followed, then usually if UMAC Status and Control Register[Quiesce Request] is written to 1 then hardware will trivially respond UMAC Status and Control Register[Quiesce Achieved] = 1
// Write to UMAC Control register(bits 4:6) with '100'
//TODO RTC 160710 for DD1 this is broken, will readd when we are on DD2
- if (C_NX_DD2_READY)
+#ifdef NX_DD2
+ fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
+ l_data.setBit<PU_UMAC_STATUS_CONTROL_QUIESCE_REQUEST>().clearBit<PU_UMAC_STATUS_CONTROL_QUIESCE_ACHEIVED>().clearBit<PU_UMAC_STATUS_CONTROL_QUIESCE_FAILED>();
+ fapi2::putScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
+
+ // Poll UMAC Control register status register (bit 5, bit 6 indicates fail)
+ for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error reading from UMAC_STATUS_CONTROL_REG");
- l_umac_status_ctrl_data.setBit<PU_UMAC_STATUS_CONTROL_QUIESCE_REQUEST>().clearBit<PU_UMAC_STATUS_CONTROL_QUIESCE_ACHEIVED>().clearBit<PU_UMAC_STATUS_CONTROL_QUIESCE_FAILED>();
- FAPI_TRY(fapi2::putScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error writing to the UMAC_STATUS_CONTROL_REG");
+ fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_data);
- // Poll UMAC Control register status register (bit 5, bit 6 indicates fail)
- for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
+ if (!l_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCE_FAILED>())
{
- FAPI_TRY(fapi2::getScom(i_target, PU_UMAC_STATUS_CONTROL, l_umac_status_ctrl_data),
- "Error reading from UMAC_STATUS_CONTROL_REG");
-
- if (l_umac_status_ctrl_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCE_ACHEIVED>())
- {
- l_quiesce_achieved = true;
- break;
- }
-
- FAPI_ASSERT(!l_umac_status_ctrl_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCE_FAILED>(),
- fapi2::P9_UMAC_QUIESCE_FAILED().set_TARGET(i_target).set_DATA(l_umac_status_ctrl_data),
- "UMAC status control quiesce failed");
+ break;
}
- FAPI_ASSERT(l_quiesce_achieved, fapi2::P9_UMAC_QUIESCE_TIMEOUT().set_TARGET(i_target).set_DATA(l_umac_status_ctrl_data),
- "UMAC status control quiesce timed out");
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- fapi_try_exit:
- FAPI_DBG("Exiting...");
- return fapi2::current_err;
- }
-
- //---------------------------------------------------------------------------------
- // NOTE: description in header
- //---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_hca_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
- {
- // Need to flush
-
- // mark HWP entry
- FAPI_DBG("Entering ...\n");
-
- //TODO RTC 160709 John said that at the point HCA looks to be out of plan. There are updates required to make functional for DD2. I am supposed to check back in a couple of months (October 2016) to confirm that it's not in plan.
- return fapi2::FAPI2_RC_SUCCESS;
+ FAPI_ASSERT(!l_data.getBit<PU_UMAC_STATUS_CONTROL_QUIESCE_FAILED>(),
+ fapi2::P9_UMAC_QUIESCE_FAILED().set_TARGET(i_target).set_DATA(l_data),
+ "UMAC status control quiesce failed");
+#endif
- /*fapi_try_exit:
- FAPI_DBG("Exiting...");
- return fapi2::current_err;*/
+ fapi_try_exit:
+ return fapi2::current_err;
}
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_psihb_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_psihb_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
fapi2::buffer<uint64_t> l_psihb_data(0);
- const uint64_t c_error_mask_disable_all = 0xFFFull;
- bool l_inbound_queue_empty = false;
+ const uint32_t c_error_mask_disable_all = 0xFFFull;
// Need mechanism to quiesce PSI DMAs
// There are bits on the PSIHB to force the DMAs to be rejected
// Disable FSP Command Enable bit in PSIHB Command/Status register
l_psihb_data.setBit<PU_PSIHB_STATUS_CTL_REG_FSP_CMD_ENABLE>().setBit<PU_PSIHB_STATUS_CTL_REG_FSP_INT_ENABLE>();
- FAPI_TRY(fapi2::putScom(i_target, PU_PSIHB_STATUS_CTL_REG_SCOM2, l_psihb_data),
- "Error writing to PSIHB_STATUS_CTL_REG");
+ fapi2::putScom(i_target, PU_PSIHB_STATUS_CTL_REG_SCOM2, l_psihb_data);
//mask all interrupts to quiesce
- l_psihb_data.flush<0>().insertFromRight<PU_PSIHB_ERROR_MASK_REG_INTERRUPT_DISABLE, PU_PSIHB_ERROR_MASK_REG_INTERRUPT_DISABLE_LEN>
+ fapi2::getScom(i_target, PU_PSIHB_ERROR_MASK_REG, l_psihb_data);
+ l_psihb_data.insertFromRight<PU_PSIHB_ERROR_MASK_REG_INTERRUPT_DISABLE, PU_PSIHB_ERROR_MASK_REG_INTERRUPT_DISABLE_LEN>
(c_error_mask_disable_all);
- FAPI_TRY(fapi2::putScom(i_target, PU_PSIHB_ERROR_MASK_REG, l_psihb_data), "Error writing to PSIHB_ERROR_MASK_REG");
+ fapi2::putScom(i_target, PU_PSIHB_ERROR_MASK_REG, l_psihb_data);
//Poll PSIHBCR bit 20 - inbound queue empty to be 0b0 for quiesce state
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_PSIHB_STATUS_CTL_REG_SCOM, l_psihb_data),
- "Error reading from PSIHB_STATUS_CTL_REG");
+ fapi2::getScom(i_target, PU_PSIHB_STATUS_CTL_REG_SCOM, l_psihb_data);
if (!l_psihb_data.getBit<PU_PSIHB_STATUS_CTL_REG_FSP_INBOUND_ACTIVE>())
{
- l_inbound_queue_empty = true;
break;
}
+
+ fapi2::delay(C_DELAY_NS_396, C_DELAY_CYCLES_396);
}
- FAPI_ASSERT(l_inbound_queue_empty, fapi2::P9_PSIHBCR_INBOUND_QUEUE_NOT_EMPTY().set_TARGET(i_target).set_DATA(
+ FAPI_ASSERT(!l_psihb_data.getBit<PU_PSIHB_STATUS_CTL_REG_FSP_INBOUND_ACTIVE>(),
+ fapi2::P9_PSIHBCR_INBOUND_QUEUE_NOT_EMPTY().set_TARGET(i_target).set_DATA(
l_psihb_data), "PSIHBCR inbound queue not empty");
+ //Disable TCE access by clearing the secure boot register - can't be done later because it's a security hole
+ l_psihb_data.flush<0>();
+ fapi2::putScom(i_target, PU_TRUST_CONTROL, l_psihb_data);
+
fapi_try_exit:
- FAPI_DBG("Exiting...");
return fapi2::current_err;
}
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
- fapi2::ReturnCode p9_intp_check_quiesce(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ fapi2::ReturnCode p9_intp_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
// mark HWP entry
- FAPI_DBG("Entering ...\n");
- fapi2::buffer<uint64_t> l_int_cq_rst_ctl_data(0);
- bool l_quiesce_achieved = false;
+ fapi2::buffer<uint64_t> l_data(0);
+ uint64_t l_int_vc_eqc_config_mask_verify_vc_syncs_complete = 0x00000000F8000000;
+ const uint64_t l_intp_scrub_masks[4] = {PU_INT_VC_IVC_SCRUB_MASK, PU_INT_VC_SBC_SCRUB_MASK, PU_INT_VC_EQC_SCRUB_MASK, PU_INT_PC_VPC_SCRUB_MASK};
// Read INT_CQ_RST_CTL so that we don't override anything
- FAPI_TRY(fapi2::getScom(i_target, PU_INT_CQ_RST_CTL, l_int_cq_rst_ctl_data),
- "Error reading INT_CQ_RST_CTL register to get initial value");
+ fapi2::getScom(i_target, PU_INT_CQ_RST_CTL, l_data);
// Set bit in INT_CQ_RST_CTL to request quiesce
- l_int_cq_rst_ctl_data.setBit<PU_INT_CQ_RST_CTL_QUIESCE_PB>();
- FAPI_TRY(fapi2::putScom(i_target, PU_INT_CQ_RST_CTL, l_int_cq_rst_ctl_data), "Error writing INT_CQ_RST_CTL register");
+ l_data.setBit<PU_INT_CQ_RST_CTL_QUIESCE_PB>();
+ fapi2::putScom(i_target, PU_INT_CQ_RST_CTL, l_data);
// Poll master and slave quiesced via bits in RST_CTL
for (uint32_t i = 0; i < C_NUM_TRIES_QUIESCE_STATE; i++)
{
- FAPI_TRY(fapi2::getScom(i_target, PU_INT_CQ_RST_CTL, l_int_cq_rst_ctl_data),
- "Error reading INT_CQ_RST_CTL register to poll quiesce bits");
+ fapi2::getScom(i_target, PU_INT_CQ_RST_CTL, l_data);
- if (l_int_cq_rst_ctl_data.getBit<PU_INT_CQ_RST_CTL_MASTER_IDLE>()
- && l_int_cq_rst_ctl_data.getBit<PU_INT_CQ_RST_CTL_SLAVE_IDLE>())
+ if (l_data.getBit<PU_INT_CQ_RST_CTL_MASTER_IDLE>() && l_data.getBit<PU_INT_CQ_RST_CTL_SLAVE_IDLE>())
{
- l_quiesce_achieved = true;
break;
}
+
+ fapi2::delay(C_INTP_DELAY_NS, C_INTP_DELAY_CYCLES);
}
- FAPI_ASSERT(l_quiesce_achieved, fapi2::P9_INTP_QUIESCE_TIMEOUT().set_TARGET(i_target).set_DATA(
- l_int_cq_rst_ctl_data), "INTP master or slave is not IDLE");
+ FAPI_ASSERT((l_data.getBit<PU_INT_CQ_RST_CTL_MASTER_IDLE>()
+ && l_data.getBit<PU_INT_CQ_RST_CTL_SLAVE_IDLE>()), fapi2::P9_INTP_QUIESCE_TIMEOUT().set_TARGET(i_target).set_DATA(
+ l_data), "INTP master or slave is not IDLE");
//Set sync_reset in RST_CTL
- l_int_cq_rst_ctl_data.setBit<PU_INT_CQ_RST_CTL_SYNC_RESET>();
- FAPI_TRY(fapi2::putScom(i_target, PU_INT_CQ_RST_CTL, l_int_cq_rst_ctl_data),
- "Error writing INT_CQ_RST_CTL register to set reset");
+ //TODO For DD1 this is broken - readd when fixed in DD2
+#ifdef INT_DD2
+ l_data.setBit<PU_INT_CQ_RST_CTL_SYNC_RESET>();
+ fapi2::putScom(i_target, PU_INT_CQ_RST_CTL, l_data);
+#else
+ //Workaround for the sync reset
+ //Verify VC syncs complete and then reset sync done bits
+ fapi2::getScom(i_target, PU_INT_VC_EQC_CONFIG, l_data);
+ FAPI_ASSERT((l_data & l_int_vc_eqc_config_mask_verify_vc_syncs_complete) ==
+ l_int_vc_eqc_config_mask_verify_vc_syncs_complete,
+ fapi2::P9_INT_WORKAROUND_ERR().set_TARGET(i_target).set_ADDRESS(PU_INT_VC_EQC_CONFIG).set_DATA(l_data),
+ "Error with VC syncs not being set as expected");
+ l_data.clearBit<32>().clearBit<33>().clearBit<34>().clearBit<35>().clearBit<36>();
+ fapi2::putScom(i_target, PU_INT_VC_EQC_CONFIG, l_data);
+
+ //---------------------------
+ //Scrub all Int caches
+ //---------------------------
+ //Fill the scrub mask regs to 0
+ for (uint32_t i = 0; i < 4; i++)
+ {
+ fapi2::putScom(i_target, l_intp_scrub_masks[i], 0x0000000000000000);
+ }
+
+ //Start the scrub operation in all caches andPoll for completion
+ FAPI_TRY(p9_int_scrub_caches(i_target), "Error scrubbing the caches");
+
+ //----------------------------
+ //Change all VSDs to invalid
+ //----------------------------
+ //Change all VC VSDs
+ //Do the IVE VC VSD
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_ADDR, 0x8000000000000000);
+
+ for (uint32_t i = 0; i < 16; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+ //Do the ESB VC VSD
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_ADDR, 0x8001000000000000);
+
+ for (uint32_t i = 0; i < 16; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Do the EQD VC VSD
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_ADDR, 0x8002000000000000);
+
+ for (uint32_t i = 0; i < 16; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Do the VPD VC VSD
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_ADDR, 0x8003000000000000);
+
+ for (uint32_t i = 0; i < 32; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Do the IRQ VC VSD
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_ADDR, 0x8004000000000000);
+
+ for (uint32_t i = 0; i < 6; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_VC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Change all PC VSDs
+ //Do the IVE PC VSD
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_ADDR, 0x8000000000000000);
+
+ for (uint32_t i = 0; i < 16; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Do the ESB PC VSD
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_ADDR, 0x8001000000000000);
+
+ for (uint32_t i = 0; i < 16; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Do the EQD PC VSD
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_ADDR, 0x8002000000000000);
+
+ for (uint32_t i = 0; i < 16; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //Do the VPD PC VSD
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_ADDR, 0x8002000000000000);
+
+ for (uint32_t i = 0; i < 32; i++)
+ {
+ fapi2::putScom(i_target, PU_INT_PC_VSD_TABLE_DATA, 0x0000000000000000);
+ }
+
+ //----------------------------
+ //Re-scrub all Int caches
+ //----------------------------
+ //Start the scrub operation in all caches and Poll for completion
+ FAPI_TRY(p9_int_scrub_caches(i_target), "Error re-scrubbing the caches");
+ //----------------------------
+ //Disable all thread contexts (this will also trigger an internal reset)
+ //----------------------------
+ fapi2::putScom(i_target, PU_INT_TCTXT_EN0, 0x0000000000000000);
+ fapi2::putScom(i_target, PU_INT_TCTXT_EN1, 0x0000000000000000);
+
+ //----------------------------
+ //Reset Quiesce
+ //----------------------------
+ fapi2::putScom(i_target, PU_INT_CQ_RST_CTL, 0x0000000000000000);
+#endif
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ //This is a helper function to scrub all the caches for Int
+ fapi2::ReturnCode p9_int_scrub_caches(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_scrub_trig_data(0);
+ const uint64_t l_scrub_addrs[4] = {PU_INT_VC_IVC_SCRUB_TRIG, PU_INT_VC_SBC_SCRUB_TRIG, PU_INT_VC_EQC_SCRUB_TRIG, PU_INT_PC_VPC_SCRUB_TRIG};
+
+ //Start the scrub operation in all caches
+ for (uint32_t i = 0; i < 4; i++)
+ {
+ fapi2::putScom(i_target, l_scrub_addrs[i], 0xA000000000000000);
+
+ for (uint32_t i = 0; i < 10000; i++)
+ {
+ fapi2::delay(C_INTP_DELAY_NS, C_INTP_DELAY_CYCLES);
+ fapi2::getScom(i_target, l_scrub_addrs[i], l_scrub_trig_data);
+
+ if (!l_scrub_trig_data.getBit<0>())
+ {
+ break;
+ }
+ }
+
+ FAPI_ASSERT(!l_scrub_trig_data.getBit<0>(),
+ fapi2::P9_INT_WORKAROUND_ERR().set_TARGET(i_target).set_ADDRESS(l_scrub_addrs[i]).set_DATA(l_scrub_trig_data),
+ "INT_VC_IVC_SCRUB_TRIG register is not complete");
+ }
fapi_try_exit:
- FAPI_DBG("Exiting...");
return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.H b/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.H
index 1163180d..5dda788b 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.H
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER sbe Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -84,12 +84,6 @@ extern "C" {
fapi2::ReturnCode p9_sbe_check_quiesce(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
- /// @brief Helper function to check the quiesce on EC/EQ
- /// @param[in] i_target => P9 chip target
- /// @return FAPI_RC_SUCCESS if the check_quiesce completes successfully
- fapi2::ReturnCode p9_ec_eq_check_quiesce(
- const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
-
/// @brief Helper function to check the quiesce for CAPP
/// @param[in] i_target => P9 chip target
/// @return FAPI_RC_SUCCESS if the check_quiesce completes successfully
@@ -114,12 +108,6 @@ extern "C" {
fapi2::ReturnCode p9_nx_check_quiesce(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
- /// @brief Helper function to check the quiesce for HCA
- /// @param[in] i_target => P9 chip target
- /// @return FAPI_RC_SUCCESS if the check_quiesce completes successfully
- fapi2::ReturnCode p9_hca_check_quiesce(
- const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
-
/// @brief Helper function to check the quiesce for PSIHB
/// @param[in] i_target => P9 chip target
/// @return FAPI_RC_SUCCESS if the check_quiesce completes successfully
@@ -138,6 +126,8 @@ extern "C" {
fapi2::ReturnCode p9_intp_check_quiesce(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
+ fapi2::ReturnCode p9_int_scrub_caches(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
+
} //extern "C"
#endif //_P9_SBE_CHECK_QUIESCE_H_
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_quiesce_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_quiesce_errors.xml
index 7670ef6e..901703d8 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_quiesce_errors.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_quiesce_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER sbe Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2017 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -54,12 +54,8 @@
The NTLs are not all in the reset state for the NPU
</description>
<ffdc>TARGET</ffdc>
- <ffdc>NTL_DATA0</ffdc>
- <ffdc>NTL_DATA1</ffdc>
- <ffdc>NTL_DATA2</ffdc>
- <ffdc>NTL_DATA3</ffdc>
- <ffdc>NTL_DATA4</ffdc>
- <ffdc>NTL_DATA5</ffdc>
+ <ffdc>NTL_ADDR</ffdc>
+ <ffdc>NTL_DATA</ffdc>
</hwpError>
<!-- ******************************************************************** -->
<hwpError>
@@ -67,7 +63,7 @@
<rc>RC_P9_VAS_QUIESCE_TIMEOUT</rc>
<description>
Procedure: p9_sbe_check_quiesce
- The VAS quiesce was not achieved
+ The VAS quiesce was not achieved
</description>
<ffdc>TARGET</ffdc>
<ffdc>NORTHDATA</ffdc>
@@ -79,7 +75,7 @@
<rc>RC_P9_NX_PBI_WRITE_IDLE_TIMEOUT</rc>
<description>
Procedure: p9_sbe_check_quiesce
- The PBI Write Idle never happened
+ The PBI Write Idle never happened
</description>
<ffdc>TARGET</ffdc>
<ffdc>DATA</ffdc>
@@ -207,5 +203,17 @@
<ffdc>CHECKSTOP_DATA</ffdc>
</hwpError>
<!-- ******************************************************************** -->
+ <hwpError>
+ <sbeError/>
+ <rc>RC_P9_INT_WORKAROUND_ERR</rc>
+ <description>
+ Procedure: p9_sbe_check_quiesce
+ If we hit an error in the INT unit workaround for DD1 part
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>ADDRESS</ffdc>
+ <ffdc>DATA</ffdc>
+ </hwpError>
+ <!-- ******************************************************************** -->
</hwpErrors>
OpenPOWER on IntegriCloud