summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThi Tran <thi@us.ibm.com>2015-12-11 12:49:53 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-05-18 18:06:56 -0400
commit9d7257c5f3932d0a561b6884e7c157d714b7964d (patch)
treeb10994e4c8835f27cf99d9f438e8e6a7dfb8192a /src
parentbf6752205969942a7f8fed73ce3dabe72e67c109 (diff)
downloadtalos-hostboot-9d7257c5f3932d0a561b6884e7c157d714b7964d.tar.gz
talos-hostboot-9d7257c5f3932d0a561b6884e7c157d714b7964d.zip
L2 - p9_build_smp HWPs
Change-Id: I603cc314d907653d22606329d881e9cc908468be Original-Change-Id: Ic3b000e1c9844499c478e29f2d370d037a8fc262 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/22704 Tested-by: Jenkins Server Reviewed-by: Joseph J. McGill <jmcgill@us.ibm.com> Tested-by: Auto Mirror Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: CHRISTINA L. GRAVES <clgraves@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24708 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.C520
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.H508
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_adu_constants.H107
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.C828
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.H88
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.C1197
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.H152
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.C103
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.H66
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_build_smp_errors.xml233
10 files changed, 3638 insertions, 164 deletions
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.C b/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.C
index b918ab5ea..8e2b89f53 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.C
@@ -7,7 +7,7 @@
/* */
/* EKB Project */
/* */
-/* COPYRIGHT 2015 */
+/* COPYRIGHT 2015,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,6 +46,15 @@ extern "C"
//ADU register field/bit definitions
+ // ADU Option Register field/bit definitions
+ const uint32_t FBC_ALTD_WITH_PRE_QUIESCE = 23;
+ const uint32_t FBC_ALTD_PRE_QUIESCE_COUNT_START_BIT = 28; // Bits 28:47
+ const uint32_t FBC_ALTD_PRE_QUIESCE_COUNT_NUM_OF_BITS = 20;
+
+ const uint32_t FBC_ALTD_WITH_POST_INIT = 51;
+ const uint32_t FBC_ALTD_POST_INIT_COUNT_START_BIT = 54; // Bits 54:63
+ const uint32_t FBC_ALTD_POST_INIT_COUNT_NUM_OF_BITS = 10;
+
// ADU Command Register field/bit definitions
const uint32_t ALTD_CMD_START_OP_BIT = 2;
const uint32_t ALTD_CMD_CLEAR_STATUS_BIT = 3;
@@ -69,15 +78,21 @@ extern "C"
const uint32_t ALTD_CMD_TSIZE_START_BIT = 32;
const uint32_t ALTD_CMD_TSIZE_END_BIT = 39;
- const uint32_t ALTD_CMD_TTYPE_NUM_BITS = (ALTD_CMD_TTYPE_END_BIT
- - ALTD_CMD_TTYPE_START_BIT + 1);
- const uint32_t ALTD_CMD_TSIZE_NUM_BITS = (ALTD_CMD_TSIZE_END_BIT
- - ALTD_CMD_TSIZE_START_BIT + 1);
- const uint32_t ALTD_CMD_TTYPE_CL_DMA_RD = 3; //0b0000011
- const uint32_t ALTD_CMD_TTYPE_DMA_PR_WR = 38;//0b0100110
- const uint32_t ALTD_CMD_TTYPE_CI_PR_RD = 52; //0b0110100
- const uint32_t ALTD_CMD_TTYPE_CI_PR_WR = 55; //0b0110111
+ const uint32_t ALTD_CMD_SCOPE_NUM_BITS = (ALTD_CMD_SCOPE_END_BIT -
+ ALTD_CMD_SCOPE_START_BIT) + 1;
+ const uint32_t ALTD_CMD_TTYPE_NUM_BITS = (ALTD_CMD_TTYPE_END_BIT -
+ ALTD_CMD_TTYPE_START_BIT) + 1;
+ const uint32_t ALTD_CMD_TSIZE_NUM_BITS = (ALTD_CMD_TSIZE_END_BIT -
+ ALTD_CMD_TSIZE_START_BIT) + 1;
+
+ const uint32_t ALTD_CMD_TTYPE_CL_DMA_RD = 3; //0b0000011
+ const uint32_t ALTD_CMD_TTYPE_DMA_PR_WR = 38; //0b0100110
+ const uint32_t ALTD_CMD_TTYPE_CI_PR_RD = 52; //0b0110100
+ const uint32_t ALTD_CMD_TTYPE_CI_PR_WR = 55; //0b0110111
+ const uint32_t ALTD_CMD_TTYPE_PB_OPER = 0b0111111;
+ const uint32_t ALTD_CMD_TTYPE_PMISC_OPER = 0b0110001;
+
//these should be 1, 2, 3, 4 but they are shifted over one to the left because for
//ci_pr_rd and ci_pr_w the secondary encode is 0ttt ssss0
const uint32_t ALTD_CMD_CI_TSIZE_1 = 2;
@@ -93,6 +108,15 @@ extern "C"
//I think that the secondary encoding should always be 0 for cl_dma_rd
const uint32_t ALTD_CMD_DMAR_TSIZE = 0;
+ // Values for PB/SWITCH operations
+ const uint32_t ALTD_CMD_PB_OPERATION_TSIZE = 0b00001000;
+ const uint32_t ALTD_CMD_SWITCH_ACTION_TSIZE = 0b00000010;
+ const uint32_t ALTD_CMD_SCOPE_SYSTEM = 0b00000101;
+
+ // OPTION reg values for SWITCH operation
+ const uint32_t QUIESCE_SWITCH_WAIT_COUNT = 128;
+ const uint32_t INIT_SWITCH_WAIT_COUNT = 128;
+
// ADU Status Register field/bit definitions
const uint32_t ALTD_STATUS_BUSY_BIT = 0;
const uint32_t ALTD_STATUS_WAIT_CMD_ARBIT = 1;
@@ -130,7 +154,6 @@ extern "C"
const uint32_t PROC_ADU_UTILS_ADU_HW_NS_DELAY = 100000000;
const uint32_t PROC_ADU_UTILS_ADU_SIM_CYCLE_DELAY = 100000;
-
//---------------------------------------------------------------------------------
// Function definitions
//---------------------------------------------------------------------------------
@@ -203,6 +226,45 @@ extern "C"
return rc;
}
+
+
+ ///
+ /// @brief Setup the value for ADU option register to enable
+ /// quiesce & init around a switch operation.
+ ///
+ /// @param [in] i_target Proc target
+ ///
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ fapi2::ReturnCode setQuiesceInit(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> altd_option_reg_data(0);
+
+ // Set up quiesce
+ altd_option_reg_data.setBit<FBC_ALTD_WITH_PRE_QUIESCE>();
+ altd_option_reg_data.insertFromRight<FBC_ALTD_PRE_QUIESCE_COUNT_START_BIT,
+ FBC_ALTD_PRE_QUIESCE_COUNT_NUM_OF_BITS>
+ (QUIESCE_SWITCH_WAIT_COUNT);
+
+ // Setup Post-command init
+ altd_option_reg_data.setBit<FBC_ALTD_WITH_POST_INIT>();
+ altd_option_reg_data.insertFromRight<FBC_ALTD_POST_INIT_COUNT_START_BIT,
+ FBC_ALTD_POST_INIT_COUNT_NUM_OF_BITS>
+ (INIT_SWITCH_WAIT_COUNT);
+
+ // Write to ADU option reg
+ FAPI_INF("OPTION reg value 0x%016llX", altd_option_reg_data);
+ FAPI_TRY(fapi2::putScom(i_target, PU_ALTD_OPTION_REG, altd_option_reg_data),
+ "Error writing to PU_ALTD_OPTION_REG register");
+
+ fapi_try_exit:
+ FAPI_DBG("Exiting...");
+ return fapi2::current_err;
+ }
+
//---------------------------------------------------------------------------------
// NOTE: description in header
//---------------------------------------------------------------------------------
@@ -212,111 +274,218 @@ extern "C"
const bool i_rnw,
const uint32_t i_flags)
{
- FAPI_DBG("Start");
+ FAPI_DBG("Start Addr 0x%.16llX, Flag 0x%.8X", i_address, i_flags);
+ fapi2::ReturnCode rc;
fapi2::buffer<uint64_t> altd_cmd_reg_data(0x0);
fapi2::buffer<uint64_t> altd_addr_reg_data(i_address);
fapi2::buffer<uint64_t> altd_data_reg_data(0x0);
+ fapi2::buffer<uint64_t> altd_option_reg(0x0);
+ p9_ADU_oper_flag l_myAduFlag;
+ p9_ADU_oper_flag::OperationType_t l_operType;
+ p9_ADU_oper_flag::Transaction_size_t l_transSize;
- //write to the altd_cmd_reg to set the fbc_locked bit
+ // Write to the altd_cmd_reg to set the fbc_locked bit
altd_cmd_reg_data.setBit<ALTD_CMD_LOCK_BIT>();
FAPI_TRY(fapi2::putScom(i_target, PU_ALTD_CMD_REG, altd_cmd_reg_data),
"Error writing the lock bit to ALTD_CMD Register");
- //write the address into altd_addr_reg
+ //Write the address into altd_addr_reg
+ FAPI_DBG("Write PU_ALTD_ADDR_REG 0x%.16llX, Value 0x%.16llX",
+ PU_ALTD_ADDR_REG, altd_addr_reg_data);
FAPI_TRY(fapi2::putScom(i_target, PU_ALTD_ADDR_REG, altd_addr_reg_data),
"Error writing to ALTD_ADDR Register");
- //write the altd_cmd_reg
- //set fbc_altd_rnw if it's a read
- if (i_rnw)
- {
- altd_cmd_reg_data.setBit<ALTD_CMD_RNW_BIT>();
- }
- //clear fbc_altd_rnw if it's a write
- else
- {
- altd_cmd_reg_data.clearBit<ALTD_CMD_RNW_BIT>();
- }
+ // Process input flag
+ l_myAduFlag.getFlag(i_flags);
+ l_operType = l_myAduFlag.getOperationType();
+ l_transSize = l_myAduFlag.getTransactionSize();
- //set the ttype and tsize
- //if it's a CI write/read
- if (i_flags & FLAG_CI)
+ // ---------------------------------------------
+ // Setting for DMA and CI operations
+ // ---------------------------------------------
+ if ( (l_operType == p9_ADU_oper_flag::CACHE_INHIBIT) ||
+ (l_operType == p9_ADU_oper_flag::DMA_PARTIAL) )
{
+
+ // ---------------------------------------------
+ // DMA & CI common settings
+ // ---------------------------------------------
+ // Write the altd_cmd_reg
+ // Set fbc_altd_rnw if it's a read
if (i_rnw)
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_CI_PR_RD);
+ altd_cmd_reg_data.setBit<ALTD_CMD_RNW_BIT>();
}
+ // Clear fbc_altd_rnw if it's a write
else
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_CI_PR_WR);
+ altd_cmd_reg_data.clearBit<ALTD_CMD_RNW_BIT>();
}
- //if tsize = 1
- if (((i_flags & FLAG_SIZE) >> FLAG_SIZE_SHIFT) == 1)
- {
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
- ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_1);
- }
- else if (((i_flags & FLAG_SIZE) >> FLAG_SIZE_SHIFT) == 2)
- {
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
- ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_2);
- }
- else if (((i_flags & FLAG_SIZE) >> FLAG_SIZE_SHIFT) == 4)
- {
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
- ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_4);
- }
- else
- {
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
- ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_8);
- }
- }
- //if it's not a CI write/read
- else
- {
- //if a read set dma_cl_rd
- //set the tsize to 8
- if (i_rnw)
+ // If auto-inc set the auto-inc bit
+ if (l_myAduFlag.getAutoIncrement() == true)
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_CL_DMA_RD);
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
- ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAR_TSIZE);
+ altd_cmd_reg_data.setBit<ALTD_CMD_AUTO_INC_BIT>();
}
- //if a write set pr_dma_wr
- //set the tsize to 8
- else
+
+ // ---------------------------------------------------
+ // Cache Inhibit specific: TTYPE & TSIZE
+ // ---------------------------------------------------
+ if (l_operType == p9_ADU_oper_flag::CACHE_INHIBIT)
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_DMA_PR_WR);
+ FAPI_DBG("ADU operation type: Cache Inhibited");
+
+ // Set TTYPE
+ if (i_rnw)
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_CI_PR_RD);
+ }
+ else
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_CI_PR_WR);
+ }
- if (((i_flags & FLAG_SIZE) >> FLAG_SIZE_SHIFT) == 1)
+ // Set TSIZE
+ if ( l_transSize == FLAG_SIZE_TSIZE_1 )
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_1);
+ }
+ else if ( l_transSize == FLAG_SIZE_TSIZE_2 )
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_2);
+ }
+ else if ( l_transSize == FLAG_SIZE_TSIZE_4 )
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT, ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_1);
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_4);
}
- else if (((i_flags & FLAG_SIZE) >> FLAG_SIZE_SHIFT) == 2)
+ else
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT, ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_2);
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_CI_TSIZE_8);
}
- else if (((i_flags & FLAG_SIZE) >> FLAG_SIZE_SHIFT) == 4)
+ }
+
+ // ---------------------------------------------------
+ // DMA specific: TTYPE & TSIZE
+ // ---------------------------------------------------
+ else if (l_operType == p9_ADU_oper_flag::DMA_PARTIAL)
+ {
+ FAPI_DBG("ADU operation type: DMA");
+
+ // If a read, set ALTD_CMD_TTYPE_CL_DMA_RD
+ // Set the tsize to ALTD_CMD_DMAR_TSIZE
+ if (i_rnw)
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT, ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_4);
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT, ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_CL_DMA_RD);
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAR_TSIZE);
}
+ // If a write set ALTD_CMD_TTYPE_DMA_PR_WR
+ // Set the tsize according to flag setting
else
{
- altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT, ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_8);
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT,
+ ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_DMA_PR_WR);
+
+ // Set TSIZE
+ if ( l_transSize == FLAG_SIZE_TSIZE_1 )
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_1);
+ }
+ else if ( l_transSize == FLAG_SIZE_TSIZE_2 )
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_2);
+ }
+ else if ( l_transSize == FLAG_SIZE_TSIZE_4 )
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_4);
+ }
+ else
+ {
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_DMAW_TSIZE_8);
+ }
}
}
}
- //if auto-inc set the auto-inc bit (bit 19)
- if (i_flags & FLAG_AUTOINC)
+ // ---------------------------------------------
+ // Setting for PB and PMISC operations
+ // ---------------------------------------------
+ if ( (l_operType == p9_ADU_oper_flag::PB_OPER) ||
+ (l_operType == p9_ADU_oper_flag::PMISC_OPER) )
{
- altd_cmd_reg_data.setBit<ALTD_CMD_AUTO_INC_BIT>();
+
+ // ---------------------------------------------
+ // PB & PMISC common settings
+ // ---------------------------------------------
+
+ // Set the start op bit
+ altd_cmd_reg_data.setBit<ALTD_CMD_START_OP_BIT>();
+
+ // Set operation scope
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_SCOPE_START_BIT,
+ ALTD_CMD_SCOPE_NUM_BITS>(ALTD_CMD_SCOPE_SYSTEM);
+
+ // Set DROP_PRIORITY = HIGH
+ altd_cmd_reg_data.setBit<ALTD_CMD_DROP_PRIORITY_BIT>();
+
+ // Set AXTYPE = Address only
+ altd_cmd_reg_data.setBit<ALTD_CMD_ADDRESS_ONLY_BIT>();
+
+ // Set OVERWRITE_PBINIT
+ altd_cmd_reg_data.setBit<ALTD_CMD_OVERWRITE_PBINIT_BIT>();
+
+ // Set TM_QUIESCE
+ altd_cmd_reg_data.setBit<ALTD_CMD_WITH_TM_QUIESCE_BIT>();
+
+
+ // ---------------------------------------------------
+ // PB specific: TTYPE & TSIZE
+ // ---------------------------------------------------
+ if (l_operType == p9_ADU_oper_flag::PB_OPER)
+ {
+ FAPI_DBG("ADU operation type: PB");
+
+ // Set TTYPE
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT,
+ ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_PB_OPER);
+
+ // TSIZE for PB operation is fixed value: 0b00001000
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_PB_OPERATION_TSIZE);
+ }
+
+ // ---------------------------------------------------
+ // PMISC specific: TTYPE & TSIZE
+ // ---------------------------------------------------
+ else if (l_operType == p9_ADU_oper_flag::PMISC_OPER)
+ {
+ FAPI_DBG("ADU operation type: PMISC");
+
+ // Set TTYPE
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TTYPE_START_BIT,
+ ALTD_CMD_TTYPE_NUM_BITS>(ALTD_CMD_TTYPE_PMISC_OPER);
+
+ // TSIZE for PMISC operation is fixed value: 0b00000010
+ altd_cmd_reg_data.insertFromRight<ALTD_CMD_TSIZE_START_BIT,
+ ALTD_CMD_TSIZE_NUM_BITS>(ALTD_CMD_SWITCH_ACTION_TSIZE);
+
+ // Set quiesce and init around a switch operation in option reg
+ FAPI_TRY(setQuiesceInit(i_target), "setQuiesceInit() returns error");
+ }
}
//This sets everything that should be set for the ALTD_CMD_Register
+ FAPI_INF("CMD reg value 0x%016llX", altd_cmd_reg_data);
+
FAPI_TRY(fapi2::putScom(i_target, PU_ALTD_CMD_REG, altd_cmd_reg_data),
"Error writing to ALTD_CMD Register");
@@ -332,7 +501,7 @@ extern "C"
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const bool i_firstGranule,
const uint64_t i_address,
- const uint32_t i_flags,
+ p9_ADU_oper_flag& i_aduOper,
const uint8_t i_write_data[])
{
FAPI_DBG("Start");
@@ -343,27 +512,41 @@ extern "C"
uint64_t write_data = 0x0ull;
int eccIndex = 8;
+ // Get ADU operation info from flag
+ bool l_itagMode = i_aduOper.getItagMode();
+ bool l_eccMode = i_aduOper.getEccMode();
+ bool l_overrideEccMode = i_aduOper.getEccItagOverrideMode();
+ bool l_autoIncMode = i_aduOper.getAutoIncrement();
+ bool l_fastMode = i_aduOper.getFastMode();
+ bool l_accessForceEccReg = (l_itagMode | l_eccMode | l_overrideEccMode);
+
+ // Dump ADU write settings
+ FAPI_DBG("Modes: ITAG 0x%.8X, ECC 0x%.8X, OVERRIDE_ECC 0x%.8X",
+ l_itagMode, l_eccMode, l_overrideEccMode);
+ FAPI_DBG(" AUTOINC 0x%.8X, FASTMODE 0x%.8X",
+ l_autoIncMode, l_fastMode);
+
for (int i = 0; i < 8; i++)
{
- write_data = write_data + ((uint64_t)(i_write_data) << (56 - (8 * i)));
+ write_data |= ( static_cast<uint64_t>(i_write_data[i]) << (56 - (8 * i)) );
}
fapi2::buffer<uint64_t> altd_data_reg_data(write_data);
- if ((i_flags & FLAG_ITAG) || (i_flags & FLAG_ECC) || (i_flags & FLAG_OVERWRITE_ECC))
+ if (l_accessForceEccReg == true)
{
FAPI_TRY(fapi2::getScom(i_target, PU_FORCE_ECC_REG, force_ecc_reg_data), "Error reading the FORCE_ECC Register");
}
//if we want to write the itag bit set it
- if (i_flags & FLAG_ITAG)
+ if (l_itagMode == true)
{
eccIndex++;
force_ecc_reg_data.setBit<ALTD_DATA_ITAG_BIT>();
}
//if we want to write the ecc data get the data
- if (i_flags & FLAG_ECC)
+ if (l_eccMode == true)
{
force_ecc_reg_data.insertFromRight < ALTD_DATA_TX_ECC_START_BIT,
(ALTD_DATA_TX_ECC_END_BIT - ALTD_DATA_TX_ECC_START_BIT) + 1 >
@@ -371,12 +554,12 @@ extern "C"
}
//if we want to overwrite the ecc data
- if (i_flags & FLAG_OVERWRITE_ECC)
+ if (l_overrideEccMode == true)
{
force_ecc_reg_data.setBit<ALTD_DATA_TX_ECC_OVERWRITE_BIT>();
}
- if ((i_flags & FLAG_ITAG) || (i_flags & FLAG_ECC) || (i_flags & FLAG_OVERWRITE_ECC))
+ if (l_accessForceEccReg == true)
{
FAPI_TRY(fapi2::putScom(i_target, PU_FORCE_ECC_REG, force_ecc_reg_data), "Error writing to the FORCE_ECC Register");
}
@@ -386,7 +569,7 @@ extern "C"
"Error writing to ALTD_DATA Register");
//Set the ALTD_CMD_START_OP bit to start the write(first granule for autoinc case or not autoinc)
- if (i_firstGranule || !(i_flags & adu_flags::FLAG_AUTOINC))
+ if ( i_firstGranule || (l_autoIncMode == false) )
{
//read the altd_cmd_register
FAPI_TRY(fapi2::getScom(i_target, PU_ALTD_CMD_REG, altd_cmd_reg_data), "Error reading from the ALTD_CMD_REG");
@@ -397,7 +580,7 @@ extern "C"
}
//if we are not in fastmode delay to allow time for the write to go through before we check the status
- if (!(i_flags & FLAG_FASTMODE_ADU))
+ if (l_fastMode == false)
{
FAPI_TRY(fapi2::delay(PROC_ADU_UTILS_ADU_HW_NS_DELAY,
PROC_ADU_UTILS_ADU_SIM_CYCLE_DELAY),
@@ -416,7 +599,7 @@ extern "C"
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const bool i_firstGranule,
const uint64_t i_address,
- const uint32_t i_flags,
+ p9_ADU_oper_flag& i_aduOper,
uint8_t o_read_data[])
{
FAPI_DBG("Start");
@@ -427,8 +610,18 @@ extern "C"
fapi2::buffer<uint64_t> force_ecc_reg_data;
int eccIndex = 8;
+ // Get ADU operation info from flag
+ bool l_itagMode = i_aduOper.getItagMode();
+ bool l_eccMode = i_aduOper.getEccMode();
+ bool l_autoIncMode = i_aduOper.getAutoIncrement();
+ bool l_fastMode = i_aduOper.getFastMode();
+
+ // Dump ADU read settings
+ FAPI_DBG("Modes: ITAG 0x%.8X, ECC 0x%.8X, AUTOINC 0x%.8X, FASTMODE 0x%.8X",
+ l_itagMode, l_eccMode, l_autoIncMode, l_fastMode);
+
//Set the ALTD_CMD_START_OP bit to start the read(first granule for autoinc case or not autoinc)
- if (i_firstGranule || !(i_flags & adu_flags::FLAG_AUTOINC))
+ if ( i_firstGranule || (l_autoIncMode == false) )
{
//read the altd_cmd_register
FAPI_TRY(fapi2::getScom(i_target, PU_ALTD_CMD_REG, altd_cmd_reg_data), "Error reading from the ALTD_CMD_REG");
@@ -439,7 +632,7 @@ extern "C"
}
//if we are not in fastmode delay to allow time for the read to go through before we get the data
- if (!(i_flags & FLAG_FASTMODE_ADU))
+ if ( l_fastMode == false )
{
FAPI_TRY(fapi2::delay(PROC_ADU_UTILS_ADU_HW_NS_DELAY,
PROC_ADU_UTILS_ADU_SIM_CYCLE_DELAY),
@@ -448,19 +641,19 @@ extern "C"
//if we want to include the itag and ecc data collect them before the read
- if ((i_flags & FLAG_ITAG) || (i_flags & FLAG_ECC))
+ if ( l_itagMode || l_eccMode )
{
FAPI_TRY(fapi2::getScom(i_target, PU_FORCE_ECC_REG, force_ecc_reg_data),
"Error reading from the FORCE_ECC Register");
}
- if (i_flags & FLAG_ITAG)
+ if (l_itagMode)
{
eccIndex = 9;
o_read_data[8] = force_ecc_reg_data.getBit<ALTD_DATA_ITAG_BIT>();
}
- if (i_flags & FLAG_ECC)
+ if (l_eccMode)
{
o_read_data[eccIndex] = (force_ecc_reg_data >> ALTD_DATA_TX_ECC_END_BIT) & ALTD_DATA_ECC_MASK;
}
@@ -531,54 +724,125 @@ extern "C"
fapi2::ReturnCode p9_adu_coherent_status_check(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
- const bool i_busy_bit_set_expected)
+ const adu_status_busy_handler i_busyBitHandler,
+ const bool i_addressOnlyOper,
+ bool& o_busyBitStatus)
{
FAPI_DBG("Start");
- fapi2::buffer<uint64_t> altd_status_reg_data(0x0);
- bool busyBitSetCorrectly = true;
+ fapi2::buffer<uint64_t> l_statusReg(0x0);
+ bool l_statusError = false;
- //check the ALTD_STATUS_REG
- FAPI_TRY(fapi2::getScom(i_target, PU_ALTD_STATUS_REG, altd_status_reg_data),
+ // Check the ALTD_STATUS_REG
+ FAPI_TRY(fapi2::getScom(i_target, PU_ALTD_STATUS_REG, l_statusReg),
"Error reading from ALTD_STATUS Register");
+ FAPI_DBG("PU_ALTD_STATUS_REG reg value 0x%016llX", l_statusReg);
+
+ // ---- Handle busy options ----
+
+ // Get busy bit output
+ o_busyBitStatus = l_statusReg.getBit<ALTD_STATUS_BUSY_BIT>();
+
+ // Handle busy bit according to specified input
+ if (o_busyBitStatus == true)
+ {
+ // Exit if busy
+ if (i_busyBitHandler == EXIT_ON_BUSY)
+ {
+ goto fapi_try_exit;
+ }
+ else if (i_busyBitHandler == EXPECTED_BUSY_BIT_CLEAR)
+ {
+ l_statusError = true;
+ }
+ }
+ else if (i_busyBitHandler == EXPECTED_BUSY_BIT_SET)
+ {
+ l_statusError = true;
+ }
+
+ // ---- Check for other errors ----
+ // Check the WAIT_CMD_ARBIT bit and make sure it's 0
+ // Check the ADDR_DONE bit and make sure it's set
+ // Check the DATA_DONE bit and make sure it's set
+ // Check the WAIT_RESP bit to make sure it's clear
+ // Check the OVERRUN_ERR to make sure it's clear
+ // Check the AUTOINC_ERR to make sure it's clear
+ // Check the COMMAND_ERR to make sure it's clear
+ // Check the ADDRESS_ERR to make sure it's clear
+ // Check the COMMAND_HANG_ERR to make sure it's clear
+ // Check the DATA_HANG_ERR to make sure it's clear
+ // Check the PBINIT_MISSING to make sure it's clear
+ // Check the ECC_CE to make sure it's clear
+ // Check the ECC_UE to make sure it's clear
+ // Check the ECC_SUE to make sure it's clear
+ l_statusError =
+ ( l_statusError ||
+ l_statusReg.getBit<ALTD_STATUS_WAIT_CMD_ARBIT>() ||
+ !l_statusReg.getBit<ALTD_STATUS_ADDR_DONE_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_WAIT_RESP_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_OVERRUN_ERROR_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_AUTOINC_ERR_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_COMMAND_ERR_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_ADDRESS_ERR_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_PB_OP_HANG_ERR_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_PB_DATA_HANG_ERR_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_PBINIT_MISSING_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_ECC_CE_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_ECC_UE_BIT>() ||
+ l_statusReg.getBit<ALTD_STATUS_ECC_SUE_BIT>()
+ );
+
+ // If Address only operation, do not check for ALTD_STATUS_DATA_DONE_BIT
+ if ( i_addressOnlyOper == false )
+ {
+ l_statusError |= !l_statusReg.getBit<ALTD_STATUS_DATA_DONE_BIT>();
+ }
- //If busy set is expected and the altd_status_busy bit is set or busy set is not expected and teh altd_status_busy bit is not set then the busy bit is set correctly
- if (i_busy_bit_set_expected == altd_status_reg_data.getBit<ALTD_STATUS_BUSY_BIT>())
+ // If error, display trace
+ if (l_statusError)
{
- busyBitSetCorrectly = true;
+ FAPI_ERR("Status mismatch detected");
+
+ FAPI_ERR("ADU Status bits: ");
+ FAPI_ERR(" FBC_ALTD_BUSY = %d",
+ o_busyBitStatus ? 1 : 0);
+ FAPI_ERR(" FBC_ALTD_WAIT_CMD_ARBIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_WAIT_CMD_ARBIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_ADDR_DONE_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_ADDR_DONE_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_DATA_DONE_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_DATA_DONE_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_WAIT_RESP_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_WAIT_RESP_BIT>() ? 1 : 0);
+
+ FAPI_ERR("ADU Error bits:");
+ FAPI_ERR(" ALTD_STATUS_OVERRUN_ERROR_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_OVERRUN_ERROR_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_AUTOINC_ERR_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_AUTOINC_ERR_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_COMMAND_ERR_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_COMMAND_ERR_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_ADDRESS_ERR_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_ADDRESS_ERR_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_PB_OP_HANG_ERR_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_PB_OP_HANG_ERR_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_PB_DATA_HANG_ERR_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_PB_DATA_HANG_ERR_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_PBINIT_MISSING_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_PBINIT_MISSING_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_ECC_CE_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_ECC_CE_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_ECC_UE_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_ECC_UE_BIT>() ? 1 : 0);
+ FAPI_ERR(" ALTD_STATUS_ECC_SUE_BIT = %d",
+ l_statusReg.getBit<ALTD_STATUS_ECC_SUE_BIT>() ? 1 : 0);
}
- //check the FBC_ALTD_BUSY bit and make sure it's 0 unless we are in autoinc and this is not the last granule
- //check the WAIT_CMD_ARBIT bit and make sure it's 0
- //check the ADDR_DONE bit and make sure it's set
- //check the DATA_DONE bit and make sure it's set
- //check the WAIT_RESP bit to make sure it's clear
- //check the OVERRUN_ERR to make sure it's clear
- //check the AUTOINC_ERR to make sure it's clear
- //check the COMMAND_ERR to make sure it's clear
- //check the ADDRESS_ERR to make sure it's clear
- //check the COMMAND_HANG_ERR to make sure it's clear
- //check the DATA_HANG_ERR to make sure it's clear
- //check the PBINIT_MISSING to make sure it's clear
- //check the ECC_CE to make sure it's clear
- //check the ECC_UE to make sure it's clear
- //check the ECC_SUE to make sure it's clear
- FAPI_ASSERT(( busyBitSetCorrectly
- && !altd_status_reg_data.getBit<ALTD_STATUS_WAIT_CMD_ARBIT>()
- //TODO These were causing problems when I tried running on vhdl, need to figure out what the problem is
- //&& altd_status_reg_data.getBit<ALTD_STATUS_ADDR_DONE_BIT>()
- //&& altd_status_reg_data.getBit<ALTD_STATUS_DATA_DONE_BIT>()
- //&& !altd_status_reg_data.getBit<ALTD_STATUS_WAIT_RESP_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_OVERRUN_ERROR_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_AUTOINC_ERR_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_COMMAND_ERR_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_ADDRESS_ERR_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_PB_OP_HANG_ERR_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_PB_DATA_HANG_ERR_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_PBINIT_MISSING_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_ECC_CE_BIT>() && !altd_status_reg_data.getBit<ALTD_STATUS_ECC_UE_BIT>()
- && !altd_status_reg_data.getBit<ALTD_STATUS_ECC_SUE_BIT>()),
- fapi2::P9_ADU_STATUS_REG_ERR().set_TARGET(i_target).set_STATUSREG(altd_status_reg_data), "Status Register check error");
+ FAPI_ASSERT( (l_statusError == false), fapi2::P9_ADU_STATUS_REG_ERR()
+ .set_TARGET(i_target)
+ .set_STATUSREG(l_statusReg),
+ "Status Register check error");
fapi_try_exit:
FAPI_DBG("Exiting...");
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.H b/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.H
index e819cfb84..3d8126162 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.H
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_adu_coherent_utils.H
@@ -7,7 +7,7 @@
/* */
/* EKB Project */
/* */
-/* COPYRIGHT 2015 */
+/* COPYRIGHT 2015,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,6 +42,16 @@
#include <fapi2.H>
#include <p9_adu_constants.H>
+// Definitions of how to handle Busy state of the ADU when
+// checking its status.
+enum adu_status_busy_handler
+{
+ EXPECTED_BUSY_BIT_CLEAR = 0, // Expect to be clear, error if not
+ EXPECTED_BUSY_BIT_SET = 1, // Expect to be set, error if not
+ EXIT_ON_BUSY = 2 // Return Busy status without checking
+ // any other errors.
+};
+
extern"C"
{
@@ -50,6 +60,479 @@ extern"C"
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
+// Classes
+//-----------------------------------------------------------------------------------
+///
+/// @brief Manage ADU operation flag that is used to program the
+// ADU CMD register, PU_ALTD_CMD_REG (Addr: 0x00090001)
+///
+ class p9_ADU_oper_flag
+ {
+ public:
+
+ // Type of ADU operations
+ enum OperationType_t
+ {
+ CACHE_INHIBIT = 0,
+ DMA_PARTIAL = 1,
+ PB_OPER = 2,
+ PMISC_OPER = 3,
+ };
+
+ // Transaction size
+ enum Transaction_size_t
+ {
+ TSIZE_1 = 1,
+ TSIZE_2 = 2,
+ TSIZE_4 = 4,
+ TSIZE_8 = 8,
+ };
+
+ // Constructor
+ inline p9_ADU_oper_flag()
+ : iv_operType(CACHE_INHIBIT), iv_autoInc(false), iv_lockPick(false),
+ iv_numLockAttempts(1), iv_cleanUp(true), iv_fastMode(false),
+ iv_itag(false), iv_ecc(false), iv_eccItagOverwrite(false),
+ iv_transSize(TSIZE_1)
+ {
+ }
+
+ ///
+ /// @brief Set the ADU operation type
+ ///
+ /// @param[in] i_type ADU operation type
+ ///
+ /// @return void.
+ ///
+ inline void setOperationType(const OperationType_t i_type)
+ {
+ iv_operType = i_type;
+ return;
+ }
+
+ ///
+ /// @brief Get the ADU operation type setting.
+ ///
+ /// @return iv_operType.
+ ///
+ inline const OperationType_t getOperationType(void)
+ {
+ return iv_operType;
+ }
+
+ /// @brief Set the Auto Increment option, for CI/DMA operations only.
+ ///
+ /// @param[in] i_value True: Enable auto inc; False: Disable
+ ///
+ /// @return void.
+ ///
+ inline void setAutoIncrement(bool i_value)
+ {
+ if ( (iv_operType != CACHE_INHIBIT) &&
+ (iv_operType != DMA_PARTIAL) )
+ {
+ FAPI_ERR("WARNING: Set AUTOINC for non CI/DMA operation, Operation type 0x%.8X",
+ iv_operType);
+ }
+
+ iv_autoInc = i_value;
+ return;
+ }
+
+ /// @brief Get the Auto Increment setting, for CI/DMA operations only.
+ ///
+ /// @return iv_autoInc.
+ ///
+ inline const bool getAutoIncrement(void)
+ {
+ if ( (iv_operType != CACHE_INHIBIT) &&
+ (iv_operType != DMA_PARTIAL) )
+ {
+ FAPI_ERR("WARNING: AUTOINC value is invalid for non CI/DMA operation, Operation type 0x%.8X",
+ iv_operType);
+ }
+
+ return iv_autoInc;
+ }
+
+ ///
+ /// @brief Set ADU lock control
+ ///
+ /// @param[in] i_value True: Attempt lock ADU before operation
+ /// False: No lock attempt
+ ///
+ /// @return void
+ ///
+ inline void setLockControl(bool i_value)
+ {
+ iv_lockPick = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get the ADU lock control setting.
+ ///
+ /// @return iv_lockPick.
+ ///
+ inline const bool getLockControl(void)
+ {
+ return iv_lockPick;
+ }
+
+ ///
+ /// @brief Set number of lock attempts
+ ///
+ /// @param[in] i_value Num of lock attempts to try. If still can't lock
+ /// ADU, return an error.
+ ///
+ /// @return void
+ ///
+ inline void setNumLockAttempts(uint8_t i_value)
+ {
+ if (iv_lockPick == false)
+ {
+ FAPI_ERR("WARNING: Set lock attempts value with lock pick = false");
+ }
+
+ iv_numLockAttempts = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get number of lock attempts setting.
+ ///
+ /// @return iv_numLockAttempts.
+ ///
+ inline const uint8_t getNumLockAttempts(void)
+ {
+ if (iv_lockPick == false)
+ {
+ FAPI_ERR("WARNING: Lock control is not set, num of lock attempts setting is invalid.");
+ }
+
+ return iv_numLockAttempts;
+ }
+
+ ///
+ /// @brief Clean up if operation fails
+ ///
+ /// @param[in] i_value True: Clean up and release lock if oper fails.
+ /// False: Leave ADU in fail state.
+ ///
+ /// @return void.
+ ///
+ inline void setOperFailCleanup(bool i_value)
+ {
+ iv_cleanUp = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get the clean up for failed operation setting.
+ ///
+ /// @return iv_cleanUp.
+ ///
+ inline const bool getOperFailCleanup(void)
+ {
+ return iv_cleanUp;
+ }
+
+ ///
+ /// @brief Set fast read/write mode.
+ /// For fast read/write mode, no status check. Otherwise,
+ /// do status check after every read/write.
+ ///
+ /// @param[in] i_value True: Enable fast read/write mode.
+ /// False: Disable fast read/write mode.
+ ///
+ /// @return void.
+ ///
+ inline void setFastMode(bool i_value)
+ {
+ iv_fastMode = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get the Fast mode setting.
+ ///
+ /// @return iv_fastMode.
+ ///
+ inline const bool getFastMode(void)
+ {
+ return iv_fastMode;
+ }
+
+ ///
+ /// @brief Set itag collection mode.
+ /// Collect/set itag with each 8B read/write
+ /// For a write only set if itag data should be 1
+ ///
+ /// @param[in] i_value True: Collect itag
+ /// False: Don't collect itag.
+ ///
+ /// @return void.
+ ///
+ inline void setItagMode(bool i_value)
+ {
+ iv_itag = i_value;
+ return;
+ }
+
+ ///
+ /// @brief the ITAG collection mode.
+ ///
+ /// @return iv_itag.
+ ///
+ inline const bool getItagMode(void)
+ {
+ return iv_itag;
+ }
+
+ ///
+ /// @brief Set Ecc mode.
+ /// Collect/set ecc with each 8B read/write
+ ///
+ /// @param[in] i_value True: Collect ECC
+ /// False: Don't collect ECC.
+ ///
+ /// @return void.
+ ///
+ inline void setEccMode(bool i_value)
+ {
+ iv_ecc = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get the Ecc mode setting.
+ ///
+ /// @return iv_ecc.
+ ///
+ inline const bool getEccMode(void)
+ {
+ return iv_ecc;
+ }
+
+ ///
+ /// @brief Overwrite ECC/ITAG data mode.
+ ///
+ /// @param[in] i_value Overwrite ECC
+ /// False: Don't overwrite ECC
+ ///
+ /// @return void.
+ ///
+ inline void setEccItagOverrideMode(bool i_value)
+ {
+ iv_eccItagOverwrite = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get the Overwrite ECC/ITAG data mode.
+ ///
+ /// @return iv_eccItagOverwrite.
+ ///
+ inline const bool getEccItagOverrideMode(void)
+ {
+ return iv_eccItagOverwrite;
+ }
+
+ ///
+ /// @brief Set transaction size
+ ///
+ /// @param[in] i_value Transaction size
+ ///
+ /// @return void.
+ ///
+ inline void setTransactionSize(Transaction_size_t i_value)
+ {
+ iv_transSize = i_value;
+ return;
+ }
+
+ ///
+ /// @brief Get the transaction size
+ ///
+ /// @return iv_transSize.
+ ///
+ inline const Transaction_size_t getTransactionSize(void)
+ {
+ return iv_transSize;
+ }
+
+ ///
+ /// @brief Assemble the 32-bit ADU flag based on current
+ /// info contained in this class.
+ /// This flag is to be used in ADU interface call
+ /// See flag bit definitions in p9_adu_constants.H
+ ///
+ /// @return uint32_t
+ ///
+ inline uint32_t setFlag();
+
+ ///
+ /// @brief Update the class instant variables with info
+ /// embedded in the passed in flag value.
+ ///
+ /// @return void.
+ ///
+ inline void getFlag(uint32_t i_flag);
+
+ private:
+
+ // Class variables
+ OperationType_t iv_operType; // Operation type
+ bool iv_autoInc; // Auto increment
+ bool iv_lockPick; // Lock ADU before operation
+ uint8_t iv_numLockAttempts; // Number of lock attempts
+ bool iv_cleanUp;
+ bool iv_fastMode; // Fast ADU read/write mode
+ bool iv_itag; // Itag mode
+ bool iv_ecc; // ECC mode
+ bool iv_eccItagOverwrite; // ECC/ITAG overwrite mode
+ Transaction_size_t iv_transSize; // Transaction size
+ };
+
+///
+/// See doxygen in class definition
+///
+ uint32_t p9_ADU_oper_flag::setFlag()
+ {
+ uint32_t l_aduFlag = 0;
+
+ // Operation type
+ l_aduFlag |= (iv_operType << FLAG_ADU_TTYPE_SHIFT);
+
+ // Auto Inc
+ if (iv_autoInc == true)
+ {
+ l_aduFlag |= FLAG_AUTOINC;
+ }
+
+ // Lock pick
+ if (iv_lockPick == true)
+ {
+ l_aduFlag |= FLAG_LOCK_PICK;
+ }
+
+ // Lock attempts
+ l_aduFlag |= (iv_numLockAttempts << FLAG_LOCK_TRIES_SHIFT);
+
+ // Leave dirty
+ if (iv_cleanUp == false)
+ {
+ l_aduFlag |= FLAG_LEAVE_DIRTY;
+ }
+
+ // Fast mode
+ if (iv_fastMode == true)
+ {
+ l_aduFlag |= FLAG_ADU_FASTMODE;
+ }
+
+ // Itag
+ if (iv_itag == true)
+ {
+ l_aduFlag |= FLAG_ITAG;
+ }
+
+ // ECC
+ if (iv_ecc == true)
+ {
+ l_aduFlag |= FLAG_ECC;
+ }
+
+ // Overwrite ECC
+ if (iv_eccItagOverwrite == true)
+ {
+ l_aduFlag |= FLAG_OVERWRITE_ECC;
+ }
+
+ // Transaction size
+ if (iv_transSize == TSIZE_1)
+ {
+ l_aduFlag |= FLAG_SIZE_TSIZE_1;
+ }
+ else if (iv_transSize == TSIZE_2)
+ {
+ l_aduFlag |= FLAG_SIZE_TSIZE_2;
+ }
+ else if (iv_transSize == TSIZE_4)
+ {
+ l_aduFlag |= FLAG_SIZE_TSIZE_4;
+ }
+ else if (iv_transSize == TSIZE_8)
+ {
+ l_aduFlag |= FLAG_SIZE_TSIZE_8;
+ }
+ else
+ {
+ FAPI_ERR("Invalid transaction size: iv_transSize %d", iv_transSize);
+ }
+
+ // Debug trace
+ FAPI_DBG("p9_ADU_oper_flag::setFlag()");
+ FAPI_DBG(" iv_operType 0x%.8X, iv_autoInc 0x%.8X, iv_lockPick 0x%.8X, iv_numLockAttempts 0x%.8X",
+ iv_operType, iv_autoInc, iv_lockPick, iv_numLockAttempts);
+ FAPI_DBG(" iv_cleanUp 0x%.8X, iv_fastMode 0x%.8X, iv_itag 0x%.8X, iv_ecc 0x%.8X",
+ iv_cleanUp, iv_fastMode, iv_itag, iv_ecc);
+ FAPI_DBG(" iv_eccItagOverwrite 0x%.8X, iv_transSize 0x%.8X",
+ iv_eccItagOverwrite, iv_transSize);
+ FAPI_DBG(" ADU Flag value: 0x%.8X", l_aduFlag);
+
+ return l_aduFlag;
+ }
+
+///
+/// See doxygen in class definition
+///
+ void p9_ADU_oper_flag::getFlag(const uint32_t i_flag)
+ {
+ // Decode Operation type
+ iv_operType = static_cast<OperationType_t>
+ ( (i_flag & FLAG_ADU_TTYPE) >> FLAG_ADU_TTYPE_SHIFT);
+
+ // Auto Inc
+ iv_autoInc = (i_flag & FLAG_AUTOINC);
+
+ // Lock pick
+ iv_lockPick = (i_flag & FLAG_LOCK_PICK);
+
+ // Lock attempts
+ iv_numLockAttempts = ( (i_flag & FLAG_LOCK_TRIES) >> FLAG_LOCK_TRIES_SHIFT);
+
+ // Leave dirty
+ iv_cleanUp = ~(i_flag & FLAG_LEAVE_DIRTY);
+
+ // Fast mode
+ iv_fastMode = (i_flag & FLAG_ADU_FASTMODE);
+
+ // Itag
+ iv_itag = (i_flag & FLAG_ITAG);
+
+ // ECC
+ iv_ecc = (i_flag & FLAG_ECC);
+
+ // Overwrite ECC
+ iv_eccItagOverwrite = (i_flag & FLAG_OVERWRITE_ECC);
+
+ // Transaction size
+ iv_transSize = static_cast<Transaction_size_t>
+ ( (i_flag & FLAG_SIZE) >> FLAG_ADU_SIZE_SHIFT );
+
+ // Debug trace
+ FAPI_DBG("p9_ADU_oper_flag::getFlag() - Flag value 0x%.8X", i_flag);
+ FAPI_DBG(" iv_operType 0x%.8X, iv_autoInc 0x%.8X, iv_lockPick 0x%.8X, iv_numLockAttempts 0x%.8X",
+ iv_operType, iv_autoInc, iv_lockPick, iv_numLockAttempts);
+ FAPI_DBG(" iv_cleanUp 0x%.8X, iv_fastMode 0x%.8X, iv_itag 0x%.8X, iv_ecc 0x%.8X",
+ iv_cleanUp, iv_fastMode, iv_itag, iv_ecc);
+ FAPI_DBG(" iv_eccItagOverwrite 0x%.8X, iv_transSize 0x%.8X",
+ iv_eccItagOverwrite, iv_transSize);
+ return;
+ }
+
+//-----------------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------------
@@ -94,28 +577,28 @@ extern"C"
/// @param[in] i_target => P9 chip target
/// @param[in] i_firstGranule => the first 8B granule that we are writing
/// @param[in] i_address => address for this write
-/// @param[in] i_flags => flags that contain information that the ADU needs to know to set up registers
+/// @param[in] i_aduOper => Contains information that the ADU needs to know to set up registers
/// @param[in] i_write_data => the data that is to be written to the ADU
/// @return FAPI_RC_SUCCESS if writing the ADU is a success
fapi2::ReturnCode p9_adu_coherent_adu_write(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const bool i_firstGranule,
const uint64_t i_address,
- const uint32_t i_flags,
+ p9_ADU_oper_flag& i_aduOper,
const uint8_t i_write_data[]);
/// @brief does the read for the ADU
/// @param[in] i_target => P9 chip target
/// @param[in] i_firstGranule => the first 8B granule that we are reading
/// @param[in] i_address => address for this read
-/// @param[in] i_flags => flags that contain information that the ADU needs to know to set up registers
+/// @param[in] i_aduOper => Contains information that the ADU needs to know to set up registers
/// @param[out] o_read_data => the data that is read from the ADU
/// @return FAPI_RC_SUCCESS if reading the ADU is a success
fapi2::ReturnCode p9_adu_coherent_adu_read(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const bool i_firstGranule,
const uint64_t i_address,
- const uint32_t i_flags,
+ p9_ADU_oper_flag& i_aduOper,
uint8_t o_read_data[]);
/// @brief this does a reset for the ADU
@@ -136,12 +619,21 @@ extern"C"
fapi2::ReturnCode p9_adu_coherent_clear_autoinc(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
-/// @brief this will check the status of the pba
-/// @param[in] i_target => P9 chip target
+/// @brief This function checks the status of the adu.
+/// If ADU is busy, it will handle
+///
+/// @param[in] i_target P9 chip target
+/// @param[in] i_busyBitHandler Instruction on how to handle the ADU busy
+/// @param[in] i_addressOnlyOper Indicate the check is called after an Address
+/// only operation
+/// @param[out] o_busyStatus ADU status busy bit.
+///
/// @return FAPI_RC_SUCCESS if the status check is a success
fapi2::ReturnCode p9_adu_coherent_status_check(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
- const bool i_busy_bit_set_expected);
+ const adu_status_busy_handler i_busyBitHandler,
+ const bool i_addressOnlyOper,
+ bool& o_busyBitStatus);
/// @brief this will acquire and release a lock as well as deal with any lock picking
/// @param[in] i_target => P9 chip target
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_adu_constants.H b/src/import/chips/p9/procedures/hwp/nest/p9_adu_constants.H
index effa28985..9c582e0bf 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_adu_constants.H
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_adu_constants.H
@@ -7,7 +7,7 @@
/* */
/* EKB Project */
/* */
-/* COPYRIGHT 2015 */
+/* COPYRIGHT 2015,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,39 +35,90 @@
extern "C"
{
- //----------------------------------------------------------------------------------------------
- // Constant definitions
- //----------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------
+// Constant definitions
+//----------------------------------------------------------------------------------------------
- //if the flag is more than 1 bit there will be a start and end bit for the flag
- //these give the bit position that is expected for the flags
+//if the flag is more than 1 bit there will be a start and end bit for the flag
+//these give the bit position that is expected for the flags
enum adu_flags
{
- //cache-inhibited (true = ci, false = dma partial)
- FLAG_CI = 0x80000000ull,
- //utilize ADU HW auto-increment function (true = use autoinc, false = don't use autoinc)
- FLAG_AUTOINC = 0x40000000ull,
- //pick ADU lock (if required) (true = use lock pick, false = don't pick lock)
- FLAG_LOCK_PICK = 0x20000000ull,
- //in the case of a fail with lock held, reset ADU and release lock (true = , false = )
- FLAG_LEAVE_DIRTY = 0x10000000ull,
- //check status only at the end of read/write stream (true = don't do status check, false = do status check after every read/write)
- FLAG_FASTMODE_ADU = 0x8000000ull,
- //collect/set itag with each 8B read/write (true = collect itag, false = don't collect itag) for a write only set if itag data should be 1
- FLAG_ITAG = 0x4000000ull,
- //collect/set ecc with each 8B read/write (true = collect ecc, false = don't collect ecc)
- FLAG_ECC = 0x2000000ull,
- //overwrite the ecc/itag data
- FLAG_OVERWRITE_ECC = 0x1000000ull,
- //transaction size (choice is 1, 2, 4, or 8)
- FLAG_SIZE = 0xFF0000ull,
- //number of ADU lock acquisitions to attempt before giving up or attempting lock pick
- FLAG_LOCK_TRIES = 0xFFFFull
+ // Operation type
+ // 0b000: DMA partial
+ // 0b001: Cache-inhibited
+ // 0b010: PB op
+ // 0b011: PMISC op
+ FLAG_ADU_TTYPE = 0xE0000000ull, // Bits 0:2
+
+ // Utilize ADU HW auto-increment function
+ // 0: Don't use autoinc
+ // 1: Use autoinc
+ FLAG_AUTOINC = 0x10000000ull, // Bit 3
+
+ // Pick ADU lock (if required)
+ // 0: Don't use lock pick
+ // 1: Use lock pick
+ FLAG_LOCK_PICK = 0x08000000ull, // Bit 4
+
+ // In case of a fail with lock held, reset
+ // ADU and release lock
+ // 0: Reset & release
+ // 1: Leave dirty
+ FLAG_LEAVE_DIRTY = 0x04000000ull, // Bit 5
+
+ // Check status only at the end of read/write stream
+ // 0: Do status check after every read/write
+ // 1: Don't do status check
+ FLAG_ADU_FASTMODE = 0x02000000ull, // Bit 6
+
+ // Collect/set itag with each 8B read/write
+ // For a write only set if itag data should be 1
+ // 0: Don't collect itag
+ // 1: Collect itag
+ FLAG_ITAG = 0x01000000ull, // Bit 7
+
+ // Collect/set ecc with each 8B read/write
+ // 0: Don't collect ecc
+ // 1: Collect ecc
+ FLAG_ECC = 0x00800000ull, // Bit 8
+
+ // Overwrite the ecc/itag data
+ // 0: Don't overwrite ECC
+ // 1: Overwrite ECC
+ FLAG_OVERWRITE_ECC = 0x00400000ull, // Bit 9
+
+ // Transaction size (choice is 1, 2, 4, or 8)
+ // 0b00: TSIZE_1
+ // 0b01: TSIZE_2
+ // 0b10: TSIZE_4
+ // 0b11: TSIZE_8
+ FLAG_SIZE = 0x00300000ull, // Bits 10:11
+
+ // Number of ADU lock acquisitions to attempt
+ // before giving up or attempting lock pick
+ FLAG_LOCK_TRIES = 0x000F0000, // Bit 12:15
+
+ // Reserved bits
+ FLAG_NOT_USED_BITS = 0x0000FFFF, // Bit 16:31
};
- const uint64_t FLAG_SIZE_SHIFT = 17;
+// Operation type values
+ const uint32_t FLAG_ADU_TTYPE_DMA = 0x00000000ull; // DMA partial
+ const uint32_t FLAG_ADU_TTYPE_CI = 0x20000000ull; // Cache inhibit
+ const uint32_t FLAG_ADU_TTYPE_PB = 0x40000000ull; // PB operation
+ const uint32_t FLAG_ADU_TTYPE_PMISC = 0x60000000ull; // Switch operation
+
+// Flag size values
+ const uint32_t FLAG_SIZE_TSIZE_1 = 0x00000000ull;
+ const uint32_t FLAG_SIZE_TSIZE_2 = 0x00100000ull;
+ const uint32_t FLAG_SIZE_TSIZE_4 = 0x00200000ull;
+ const uint32_t FLAG_SIZE_TSIZE_8 = 0x00300000ull;
+
+// Shift positions
+ const uint64_t FLAG_ADU_TTYPE_SHIFT = 29;
+ const uint64_t FLAG_LOCK_TRIES_SHIFT = 16;
+ const uint64_t FLAG_ADU_SIZE_SHIFT = 20;
} //extern "C"
#endif //_P9_ADU_CONSTANTS_H_
-
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.C b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.C
new file mode 100644
index 000000000..6b29158e0
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.C
@@ -0,0 +1,828 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/nest/p9_build_smp_adu.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_build_smp_adu.C
+/// @brief Interface for ADU operations required to support fabric
+/// configuration actions (FAPI2)
+///
+/// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
+/// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+/// *HWP Team: Nest
+/// *HWP Level: 2
+/// *HWP Consumed by: HB,FSP
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <p9_build_smp_adu.H>
+#include <p9_adu_coherent_utils.H>
+#include <p9_misc_scom_addresses.H>
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+// Poll threshold
+const uint32_t P9_BUILD_SMP_MAX_STATUS_POLLS = 100;
+
+// ADU lock
+const uint32_t P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS = 1;
+const bool P9_BUILD_SMP_PHASE1_ADU_PICK_LOCK = false;
+
+const uint32_t P9_BUILD_SMP_PHASE2_ADU_LOCK_ATTEMPTS = 5;
+const bool P9_BUILD_SMP_PHASE2_ADU_PICK_LOCK = true;
+
+// ADU pMISC Mode register field/bit definitions
+const uint32_t ADU_PMISC_MODE_ENABLE_PB_SWITCH_AB_BIT = 30;
+const uint32_t ADU_PMISC_MODE_ENABLE_PB_SWITCH_CD_BIT = 31;
+
+enum p9_build_smp_ffdc_reg_index
+{
+ PB_MODE_CENT_DATA_INDEX = 0,
+ PB_HP_MODE_NEXT_CENT_DATA_INDEX = 1,
+ PB_HP_MODE_CURR_CENT_DATA_INDEX = 2,
+ PB_HPX_MODE_NEXT_CENT_DATA_INDEX = 3,
+ PB_HPX_MODE_CURR_CENT_DATA_INDEX = 4,
+ X_GP0_DATA_INDEX = 5,
+ PB_X_MODE_DATA_INDEX = 6,
+ A_GP0_DATA_INDEX = 7,
+ ADU_IOS_LINK_EN_DATA_INDEX = 8,
+ PB_A_MODE_DATA_INDEX = 9,
+ ADU_PMISC_MODE_DATA_INDEX = 10
+};
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+// Function definitions
+//------------------------------------------------------------------------------
+///
+/// @brief Check ADU status matches expected state/value
+/// NOTE: intended to be run while holding ADU lock
+///
+/// @param[in] i_target P9 target
+/// @param[in] i_smp Structure encapsulating SMP topology
+/// @param[in] i_dump_all_targets Dump FFDC for all targets in SMP?
+/// true=yes; false=no (only for i_target)
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_adu_check_status(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ p9_build_smp_system& i_smp,
+ const bool i_dump_all_targets)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ uint32_t l_numPolls = 0;
+ bool l_busyBitStatus = false;
+
+ // SMP SWITCH expect BUSY BIT to be clear
+ adu_status_busy_handler l_busyHandling = EXIT_ON_BUSY;
+
+ // Wait for operation to be completed (busy bit cleared)
+ while (l_numPolls < P9_BUILD_SMP_MAX_STATUS_POLLS)
+ {
+ l_rc = p9_adu_coherent_status_check(i_target, l_busyHandling, true,
+ l_busyBitStatus);
+
+ if (l_rc)
+ {
+ FAPI_ERR("p9_adu_coherent_status_check() returns error");
+ break;
+ }
+
+ if (l_busyBitStatus == true)
+ {
+ l_numPolls++;
+
+ // Last try, set handler to expect busy bit clear, if not then
+ // p9_adu_coherent_status_check() will log an error so that
+ // we don't have to deal with the error separately here.
+ if (l_numPolls == (P9_BUILD_SMP_MAX_STATUS_POLLS - 1))
+ {
+ l_busyHandling = EXPECTED_BUSY_BIT_CLEAR;
+ }
+ }
+ else
+ {
+ // Operation done, break out
+ break;
+ }
+ }
+
+ FAPI_DBG("Num of polls %u", l_numPolls);
+
+ // TODO: RTC 147511 - Need to add code to dump FFDC
+ // Note: variable_buffer doesn't currently support resize because it's
+ // an expensive operation.
+ // Per Joe's suggestion, may be we can size statically by the maximum
+ // number of chips possible in the system. It's not efficient, but
+ // this is an error path.
+#if 0
+
+ // Additional error handling for SMP build
+ if (l_rc)
+ {
+ fapi2::current_err = l_rc;
+
+
+ // Dump FFDC
+ // There is no clean way to represent the collection in XML (given an
+ // arbitrary number of chips), so collect manually and store into data
+ // buffers which can be post-processed from the error log
+ std::map<p9_fab_smp_node_id, p9_build_smp_node>::iterator n_iter;
+ std::map<p9_fab_smp_chip_id, p9_build_smp_chip>::iterator p_iter;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>*> targets_to_collect;
+ fapi2::buffer<uint64_t> l_scomData;
+ fapi2::variable_buffer l_chipIds;
+ fapi2::variable_buffer l_ffdcRegData[P9_BUILD_SMP_FFDC_NUM_REGS];
+ bool l_ffdcScomError = false;
+
+ // Determine set of chips to collect
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ if (i_dump_all_targets ||
+ (p_iter->second.chip->this_chip == i_target))
+ {
+ targets_to_collect.push_back(
+ &(p_iter->second.chip->this_chip));
+ }
+ }
+ }
+
+ // Size the FFDC buffers
+ rc_ecmd |= chip_ids.setByteLength(targets_to_collect.size());
+
+ for (uint8_t i = 0; i < P9_BUILD_SMP_FFDC_NUM_REGS; i++)
+ {
+ rc_ecmd |= ffdc_reg_data[i].setDoubleWordLength(targets_to_collect.size());
+ }
+
+ // extract FFDC data
+ std::vector<bool>::iterator n = nv_present.begin();
+
+ for (std::vector<fapi::Target*>::iterator t = targets_to_collect.begin();
+ t != targets_to_collect.end();
+ t++, n++)
+ {
+ // log node/chip ID
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ n_iter++)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ p_iter++)
+ {
+ if ((&(p_iter->second.chip->this_chip)) == *t)
+ {
+ uint8_t id = ((n_iter->first & 0x3) << 4) |
+ (p_iter->first & 0x3);
+
+ rc_ecmd |= chip_ids.setByte(t - targets_to_collect.begin(), id);
+ }
+ }
+ }
+
+ // collect SCOM data
+ for (uint8_t i = 0; i < P9_BUILD_SMP_FFDC_NUM_REGS; i++)
+ {
+ // skip A / F link registers if NV link logic is present
+ if ((*n) &&
+ ((i == static_cast<uint8_t>(A_GP0_DATA_INDEX)) ||
+ (i == static_cast<uint8_t>(ADU_IOS_LINK_EN_DATA_INDEX)) ||
+ (i == static_cast<uint8_t>(PB_A_MODE_DATA_INDEX))))
+ {
+ rc_ecmd |= scom_data.flushTo1();
+ }
+ else
+ {
+ rc = fapiGetScom(*(*t), P9_BUILD_SMP_FFDC_REGS[i], scom_data);
+
+ if (!rc.ok())
+ {
+ ffdc_scom_error = true;
+ }
+ }
+
+ rc_ecmd |= scom_data.extractPreserve(
+ ffdc_reg_data[i],
+ 0, 64,
+ 64 * (t - targets_to_collect.begin()));
+ }
+ }
+
+ const fapi::Target& TARGET = i_target;
+ const p9_adu_utils_adu_status& ADU_STATUS_DATA = status;
+ const uint8_t& ADU_NUM_POLLS = num_polls;
+ const uint8_t& NUM_CHIPS = targets_to_collect.size();
+ const uint8_t& FFDC_VALID = !rc_ecmd && !ffdc_scom_error;
+ const ecmdDataBufferBase& CHIP_IDS = chip_ids;
+ const ecmdDataBufferBase& PB_MODE_CENT_DATA = ffdc_reg_data[0];
+ const ecmdDataBufferBase& PB_HP_MODE_NEXT_CENT_DATA = ffdc_reg_data[1];
+ const ecmdDataBufferBase& PB_HP_MODE_CURR_CENT_DATA = ffdc_reg_data[2];
+ const ecmdDataBufferBase& PB_HPX_MODE_NEXT_CENT_DATA = ffdc_reg_data[3];
+ const ecmdDataBufferBase& PB_HPX_MODE_CURR_CENT_DATA = ffdc_reg_data[4];
+ const ecmdDataBufferBase& X_GP0_DATA = ffdc_reg_data[5];
+ const ecmdDataBufferBase& PB_X_MODE_DATA = ffdc_reg_data[6];
+ const ecmdDataBufferBase& A_GP0_DATA = ffdc_reg_data[7];
+ const ecmdDataBufferBase& ADU_IOS_LINK_EN_DATA = ffdc_reg_data[8];
+ const ecmdDataBufferBase& PB_A_MODE_DATA = ffdc_reg_data[9];
+ const ecmdDataBufferBase& ADU_PMISC_MODE_DATA = ffdc_reg_data[10];
+ FAPI_SET_HWP_ERROR(rc, RC_PROC_BUILD_SMP_ADU_STATUS_MISMATCH);
+ break;
+
+ }
+
+ fapi_try_exit:
+#endif
+
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+// NOTE: see comments above function prototype in header
+ fapi2::ReturnCode p9_build_smp_quiesce_pb(p9_build_smp_system& i_smp,
+ const p9_build_smp_operation i_op)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ bool l_lockPick = false;
+ uint8_t l_numAttempts = 1;
+ uint64_t l_address = 0; // Address phase
+ p9_ADU_oper_flag l_myAduFlag;
+
+ // Node/Chip iterators
+ std::map<p9_fab_smp_node_id, p9_build_smp_node>::iterator n_iter;
+ std::map<p9_fab_smp_chip_id, p9_build_smp_chip>::iterator p_iter;
+ std::vector<p9_build_smp_chip*>::iterator quiesce_iter;
+
+ // Lock flag
+ bool adu_is_dirty = false;
+
+ FAPI_DBG("Acquiring lock for all ADU units in fabric");
+
+ // Set pick lock & num of tries
+ l_lockPick = (i_op == SMP_ACTIVATE_PHASE1) ?
+ P9_BUILD_SMP_PHASE1_ADU_PICK_LOCK :
+ P9_BUILD_SMP_PHASE2_ADU_PICK_LOCK;
+ l_numAttempts = (i_op == SMP_ACTIVATE_PHASE1) ?
+ P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS :
+ P9_BUILD_SMP_PHASE2_ADU_LOCK_ATTEMPTS;
+
+ // Loop through all chips, lock & reset ADU
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ // Acquire ADU lock
+ FAPI_TRY(p9_adu_coherent_manage_lock(
+ p_iter->second.chip->this_chip,
+ l_lockPick,
+ true, // Acquire lock
+ l_numAttempts),
+ "p9_adu_coherent_manage_lock() - Lock returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // NOTE: lock is now held, if an operation fails from this point
+ // to the end of the procedure:
+ // o attempt to cleanup/release lock (so that procedure does
+ // not leave the ADU in a locked state)
+ // o return rc of original fail
+ adu_is_dirty = true;
+
+ // Reset ADU
+ l_rc = p9_adu_coherent_utils_reset_adu(
+ p_iter->second.chip->this_chip);
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_adu_coherent_utils_reset_adu()");
+ goto adu_reset_unlock;
+ }
+ }
+ }
+
+ FAPI_DBG("All ADU locks held");
+
+ // Setup ADU flag to peform quiesce
+ l_myAduFlag.setOperationType(p9_ADU_oper_flag::PB_OPER);
+
+ // Issue quiesce on all specified chips
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ if (p_iter->second.issue_quiesce_next)
+ {
+ char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
+ fapi2::toString(p_iter->second.chip->this_chip, l_targetStr,
+ sizeof(l_targetStr));
+ FAPI_INF("Issuing quiesce from %s", l_targetStr);
+
+ // Setup and launch command
+ l_rc = p9_adu_coherent_setup_adu(p_iter->second.chip->this_chip,
+ l_address,
+ false, // write
+ l_myAduFlag.setFlag());
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_adu_coherent_setup_adu()");
+ goto adu_reset_unlock;
+ }
+
+ // Check status
+ l_rc = p9_build_smp_adu_check_status(
+ p_iter->second.chip->this_chip,
+ i_smp,
+ (i_op == SMP_ACTIVATE_PHASE2));
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_build_smp_adu_check_status");
+ goto adu_reset_unlock;
+ }
+ }
+ }
+ }
+
+ // Loop through all chips, unlock ADUs
+ FAPI_DBG("Releasing lock for all ADU units in drawer");
+
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ // Release ADU lock
+ l_lockPick = false;
+ l_numAttempts = (i_op == SMP_ACTIVATE_PHASE1) ?
+ P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS :
+ P9_BUILD_SMP_PHASE2_ADU_LOCK_ATTEMPTS;
+ FAPI_TRY(p9_adu_coherent_manage_lock(p_iter->second.chip->this_chip,
+ l_lockPick,
+ false, // Release lock
+ l_numAttempts),
+ "p9_adu_coherent_manage_lock() - Release returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ FAPI_DBG("All ADU locks released");
+ // No error for entire operation, ADU locks released.
+ adu_is_dirty = false;
+
+ adu_reset_unlock:
+
+ // If error has occurred and any ADU is dirty,
+ // attempt to reset all ADUs and free locks (propogate rc of original fail)
+ if (l_rc && adu_is_dirty)
+ {
+ // Save original error
+ fapi2::ReturnCode l_savedRc = l_rc;
+
+ FAPI_INF("Attempting to reset/free lock on all ADUs");
+
+ // loop through all chips, unlock ADUs
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ // Ignore l_rc1 when attempting to reset/unlock
+ l_rc = p9_adu_coherent_utils_reset_adu(
+ p_iter->second.chip->this_chip);
+ l_rc = p9_adu_coherent_manage_lock(
+ p_iter->second.chip->this_chip,
+ false, // No lock pick
+ false, // Lock release
+ 1); // Attempt 1 time
+ }
+ }
+
+ // Return original error
+ fapi2::current_err = l_savedRc;
+ }
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+///
+/// @brief Set action which will occur on fabric pmisc switch command
+/// NOTE: intended to be run while holding ADU lock
+///
+/// @param[in] i_target P9 target
+/// @param[in] i_switch_ab Perform switch AB operation?
+/// @param[in] i_switch_cd Perform switch CD operation?
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_adu_set_switch_action(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const bool i_switch_ab,
+ const bool i_switch_cd)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+
+ fapi2::buffer<uint64_t> pmisc_data;
+ fapi2::buffer<uint64_t> pmisc_mask;
+
+ // Build ADU pMisc Mode register content
+ FAPI_DBG("Writing ADU pMisc Mode register. Switch_ab %s, Switch_cd %s",
+ i_switch_ab ? "true" : "false", i_switch_cd ? "true" : "false");
+
+ // Switch AB bit
+ pmisc_data.writeBit<ADU_PMISC_MODE_ENABLE_PB_SWITCH_AB_BIT>(i_switch_ab);
+ pmisc_mask.setBit<ADU_PMISC_MODE_ENABLE_PB_SWITCH_AB_BIT>();
+
+ // Switch CD bit
+ pmisc_data.writeBit<ADU_PMISC_MODE_ENABLE_PB_SWITCH_CD_BIT>(i_switch_cd);
+ pmisc_mask.setBit<ADU_PMISC_MODE_ENABLE_PB_SWITCH_CD_BIT>();
+
+ FAPI_TRY(fapi2::putScomUnderMask(i_target, PU_SND_MODE_REG,
+ pmisc_data, pmisc_mask),
+ "putScomUnderMask() returns an error. Address 0x%.16llX", PU_SND_MODE_REG);
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+// NOTE: see comments above function prototype in header
+ fapi2::ReturnCode p9_build_smp_switch_ab(p9_build_smp_system& i_smp,
+ const p9_build_smp_operation i_op)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ p9_ADU_oper_flag l_myAduFlag;
+
+ // Chip/Node map iterators
+ std::map<p9_fab_smp_node_id, p9_build_smp_node>::iterator n_iter;
+ std::map<p9_fab_smp_chip_id, p9_build_smp_chip>::iterator p_iter;
+
+ // Lock flag
+ bool adu_is_dirty = false;
+ bool l_lockPick = false;
+ uint8_t l_numAttempts = 1;
+ uint64_t l_address = 0; // Address phase
+
+ // Loop through all chips, lock & reset ADU & set switch action
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ // Set pick lock & num of tries
+ l_lockPick = (i_op == SMP_ACTIVATE_PHASE1) ?
+ P9_BUILD_SMP_PHASE1_ADU_PICK_LOCK :
+ P9_BUILD_SMP_PHASE2_ADU_PICK_LOCK;
+ l_numAttempts = (i_op == SMP_ACTIVATE_PHASE1) ?
+ P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS :
+ P9_BUILD_SMP_PHASE2_ADU_LOCK_ATTEMPTS;
+
+ // Acquire ADU lock
+ FAPI_TRY(p9_adu_coherent_manage_lock(
+ p_iter->second.chip->this_chip,
+ l_lockPick,
+ true, // Acquire lock
+ l_numAttempts),
+ "p9_adu_coherent_manage_lock() - Lock returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // NOTE: lock is now held, if an operation fails from this point
+ // to the end of the procedure:
+ // o attempt to cleanup/release lock (so that procedure does
+ // not leave the ADU in a locked state)
+ // o return rc of original fail
+ adu_is_dirty = true;
+
+ // Reset ADU
+ l_rc = p9_adu_coherent_utils_reset_adu(
+ p_iter->second.chip->this_chip);
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_adu_coherent_utils_reset_adu()");
+ goto adu_reset_unlock;
+ }
+
+ // Condition for switch AB operation
+ // all chips which were not quiesced prior to switch AB will
+ // need to observe the switch
+ l_rc = p9_build_smp_adu_set_switch_action(
+ p_iter->second.chip->this_chip,
+ !p_iter->second.quiesced_next,
+ false);
+
+ if (l_rc)
+ {
+ FAPI_ERR("(Set): Error from p9_build_smp_adu_set_switch_action()");
+ goto adu_reset_unlock;
+ }
+ }
+ }
+
+ FAPI_DBG("All ADU locks held");
+
+ // Setup ADU flag to peform switch
+ l_myAduFlag.setOperationType(p9_ADU_oper_flag::PMISC_OPER);
+
+ char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
+ fapi2::toString(i_smp.nodes[i_smp.master_chip_curr_node_id].chips[i_smp.master_chip_curr_chip_id].chip->this_chip,
+ l_targetStr,
+ sizeof(l_targetStr));
+ FAPI_INF("Issuing switch AB from %s", l_targetStr);
+
+ // Setup and launch command
+ l_rc = p9_adu_coherent_setup_adu(
+ i_smp.nodes[i_smp.master_chip_curr_node_id].chips[i_smp.master_chip_curr_chip_id].chip->this_chip,
+ l_address,
+ false, // write
+ l_myAduFlag.setFlag());
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_adu_coherent_setup_adu()");
+ goto adu_reset_unlock;
+ }
+
+ // Check status
+ l_rc = p9_build_smp_adu_check_status(
+ i_smp.nodes[i_smp.master_chip_curr_node_id].chips[i_smp.master_chip_curr_chip_id].chip->this_chip,
+ i_smp,
+ (i_op == SMP_ACTIVATE_PHASE2));
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_build_smp_adu_check_status");
+ goto adu_reset_unlock;
+ }
+
+ // Loop through all chips, unlock ADUs
+ FAPI_DBG("Releasing lock for all ADU units in drawer");
+
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ // Release ADU lock
+ l_lockPick = false;
+ l_numAttempts = (i_op == SMP_ACTIVATE_PHASE1) ?
+ P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS :
+ P9_BUILD_SMP_PHASE2_ADU_LOCK_ATTEMPTS;
+ FAPI_TRY(p9_adu_coherent_manage_lock(p_iter->second.chip->this_chip,
+ l_lockPick,
+ false, l_numAttempts),
+ "p9_adu_coherent_manage_lock() - Release returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ FAPI_DBG("All ADU locks released");
+ // No error for entire operation, ADU locks released.
+ adu_is_dirty = false;
+
+ adu_reset_unlock:
+
+ // If error has occurred and any ADU is dirty,
+ // attempt to reset all ADUs and free locks (propogate rc of original fail)
+ if (l_rc && adu_is_dirty)
+ {
+ // Save original error
+ fapi2::ReturnCode l_savedRc = l_rc;
+
+ FAPI_INF("Attempting to reset/free lock on all ADUs");
+
+ // loop through all chips, unlock ADUs
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ // Ignore l_rc when attempting to reset/unlock
+ l_rc = p9_build_smp_adu_set_switch_action(
+ p_iter->second.chip->this_chip,
+ false, false);
+ l_rc = p9_adu_coherent_utils_reset_adu(
+ p_iter->second.chip->this_chip);
+ l_rc = p9_adu_coherent_manage_lock(
+ p_iter->second.chip->this_chip,
+ false, // No lock pick
+ false, // Lock release
+ 1); // Attempt 1 time
+ }
+ }
+
+ // Return original error
+ fapi2::current_err = l_savedRc;
+ }
+
+ fapi_try_exit:
+
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+// NOTE: see comments above function prototype in header
+ fapi2::ReturnCode p9_build_smp_switch_cd(
+ p9_build_smp_chip& i_smp_chip,
+ p9_build_smp_system& i_smp)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ p9_ADU_oper_flag l_myAduFlag;
+
+ // Lock flag
+ bool adu_is_dirty = false;
+ bool l_lockPick = false;
+ uint8_t l_numAttempts = 1;
+ uint64_t l_address = 0; // Address phase
+
+ FAPI_DBG("Acquiring lock for ADU");
+
+ // Acquire ADU lock
+ // only required to obtain lock for this chip, as this function will
+ // only be executed when fabric is configured as single chip island
+
+ // Set pick lock & num of tries
+ l_lockPick = P9_BUILD_SMP_PHASE1_ADU_PICK_LOCK;
+ l_numAttempts = P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS;
+
+ // Acquire ADU lock
+ FAPI_TRY(p9_adu_coherent_manage_lock(
+ i_smp_chip.chip->this_chip,
+ l_lockPick,
+ true, // Acquire lock
+ l_numAttempts),
+ "p9_adu_coherent_manage_lock() - Lock returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // NOTE: lock is now held, if an operation fails from this point
+ // to the end of the procedure:
+ // o attempt to cleanup/release lock (so that procedure does
+ // not leave the ADU in a locked state)
+ // o return rc of original fail
+ adu_is_dirty = true;
+
+ // Reset ADU
+ l_rc = p9_adu_coherent_utils_reset_adu(i_smp_chip.chip->this_chip);
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_adu_coherent_utils_reset_adu()");
+ goto adu_reset_unlock;
+ }
+
+ // Condition for switch CD operation
+ l_rc = p9_build_smp_adu_set_switch_action(i_smp_chip.chip->this_chip,
+ false, // Switch A/B
+ true); // Switch C/D
+
+ if (l_rc)
+ {
+ FAPI_ERR("(Set): Error from p9_build_smp_adu_set_switch_action()");
+ goto adu_reset_unlock;
+ }
+
+
+ FAPI_DBG("All ADU locks held");
+
+ // Setup ADU flag to peform switch
+ l_myAduFlag.setOperationType(p9_ADU_oper_flag::PMISC_OPER);
+
+ char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
+ fapi2::toString(i_smp_chip.chip->this_chip, l_targetStr,
+ sizeof(l_targetStr));
+ FAPI_INF("Issuing switch CD from %s", l_targetStr);
+
+ // Setup and launch command
+ l_rc = p9_adu_coherent_setup_adu(i_smp_chip.chip->this_chip,
+ l_address,
+ false, // write
+ l_myAduFlag.setFlag());
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_adu_coherent_setup_adu()");
+ goto adu_reset_unlock;
+ }
+
+ // Check status
+ l_rc = p9_build_smp_adu_check_status(i_smp_chip.chip->this_chip,
+ i_smp, false);
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9_build_smp_adu_check_status");
+ goto adu_reset_unlock;
+ }
+
+ // Reset switch controls
+ l_rc = p9_build_smp_adu_set_switch_action(i_smp_chip.chip->this_chip,
+ false, false);
+
+ if (l_rc)
+ {
+ FAPI_ERR("(Reset): Error from p9_build_smp_adu_set_switch_action()");
+ goto adu_reset_unlock;
+ }
+
+ // Release ADU lock
+ FAPI_DBG("Releasing lock for ADU");
+ l_lockPick = false;
+ l_numAttempts = P9_BUILD_SMP_PHASE1_ADU_LOCK_ATTEMPTS;
+ FAPI_TRY(p9_adu_coherent_manage_lock(i_smp_chip.chip->this_chip,
+ l_lockPick,
+ false, // Release
+ l_numAttempts),
+ "p9_adu_coherent_manage_lock() - Release returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ FAPI_DBG("All ADU locks released");
+ // No error for entire operation, ADU locks released.
+ adu_is_dirty = false;
+
+ adu_reset_unlock:
+
+ // If error has occurred and any ADU is dirty,
+ // attempt to reset all ADUs and free locks (propogate rc of original fail)
+ if (l_rc && adu_is_dirty)
+ {
+ FAPI_INF("Attempting to reset/free lock on ADU");
+
+ // Save original error
+ fapi2::ReturnCode l_savedRc = l_rc;
+
+ // Ignore l_rc when attempting to reset/unlock
+ l_rc = p9_build_smp_adu_set_switch_action(i_smp_chip.chip->this_chip,
+ false, false);
+ l_rc = p9_adu_coherent_utils_reset_adu(i_smp_chip.chip->this_chip);
+ l_rc = p9_adu_coherent_manage_lock(i_smp_chip.chip->this_chip,
+ false, // No lock pick
+ false, // Lock release
+ 1); // Attempt 1 time
+ // Return original error
+ fapi2::current_err = l_savedRc;
+ }
+
+ fapi_try_exit:
+
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+} // extern "C"
+
+
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.H b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.H
new file mode 100644
index 000000000..4d986921a
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_adu.H
@@ -0,0 +1,88 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/nest/p9_build_smp_adu.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_build_smp_adu.H
+/// @brief Interface for ADU operations required to support fabric
+/// configuration actions (FAPI2)
+///
+/// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
+/// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+/// *HWP Team: Nest
+/// *HWP Level: 2
+/// *HWP Consumed by: HB,FSP
+///
+
+#ifndef _P9_BUILD_SMP_ADU_H_
+#define _P9_BUILD_SMP_ADU_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+#include <p9_build_smp.H>
+
+extern "C" {
+
+//------------------------------------------------------------------------------
+// Function prototypes
+//------------------------------------------------------------------------------
+
+///
+/// @brief Perform fabric C/D configuration switch on a single chip
+///
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_smp Structure encapsulating SMP topology
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_switch_cd(p9_build_smp_chip& i_smp_chip,
+ p9_build_smp_system& i_smp);
+
+///
+/// @brief Quiesce slave fabrics by issuing fabric quiesce operation on
+/// specified chips
+/// NOTE: ADU atomic lock will be obtained for all chips prior
+/// to issuing quiesce operation on specified chips
+///
+/// @param[in] i_smp Structure encapsulating SMP topology
+/// @param[in] i_op Enumerated type representing SMP build phase
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_quiesce_pb(p9_build_smp_system& i_smp,
+ const p9_build_smp_operation i_op);
+
+
+///
+/// @brief Perform fabric A/B configuration switch on all chips present in SMP
+/// NOTE: ADU atomic lock will be obtained for all chips prior to
+/// issuing switch from master chip (defined by i_master_smp_chip)
+///
+/// @param[in] i_smp Structure encapsulating SMP topology
+/// @param[in] i_op Enumerated type representing SMP build phase
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_switch_ab(p9_build_smp_system& i_smp,
+ const p9_build_smp_operation i_op);
+
+
+} // extern "C"
+
+#endif // _P9_BUILD_SMP_ADU_H_
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.C b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.C
new file mode 100644
index 000000000..b51612afb
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.C
@@ -0,0 +1,1197 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_build_smp_fbc_ab.C
+///
+/// @brief Fabric configuration (hotplug, AB) functions.
+///
+/// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
+/// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+/// *HWP Team: Nest
+/// *HWP Level: 2
+/// *HWP Consumed by: HB,FSP
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <p9_build_smp_fbc_ab.H>
+#include <p9_build_smp_adu.H>
+#include <p9_fab_smp_utils.H>
+#include <p9_build_smp_epsilon.H>
+#include <p9_misc_scom_addresses.H>
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+// The start/end bits for each link in each link delay regs are the same
+const uint32_t OPTIC_EVEN_LINK_DELAY_START_BIT[P9_FAB_SMP_NUM_OPTIC_LINKS] =
+{ 4, 36, 4, 36 };
+
+const uint32_t X_EVEN_LINK_DELAY_START_BIT[P9_FAB_SMP_NUM_X_LINKS] =
+{ 4, 36, 4 };
+
+// All link delays have same bit len
+const uint32_t LINK_DELAY_BIT_LEN = 12;
+
+//------------------------------------------------------------------------------
+// Function definitions
+//------------------------------------------------------------------------------
+
+// See doxygen in header file
+template<fapi2::TargetType T>
+fapi2::ReturnCode p9_build_smp_query_link_state(
+ const p9_build_smp_chip& i_smp_chip,
+ const uint8_t i_source_link_id,
+ const fapi2::Target<T>& i_dest_target,
+ bool& o_link_is_enabled,
+ p9_fab_smp_node_id& o_dest_target_node_id,
+ p9_fab_smp_chip_id& o_dest_target_chip_id)
+{
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+
+ if (fapi2::is_same<T, fapi2::TARGET_TYPE_XBUS>())
+ {
+ FAPI_DBG("Bus type %s, SourceId %d", "X-BUS", i_source_link_id);
+ }
+ else if (fapi2::is_same<T, fapi2::TARGET_TYPE_OBUS>())
+ {
+ FAPI_DBG("Bus type %s, SourceId %d", "O-BUS", i_source_link_id);
+ }
+
+ // TODO: RTC 147511 - Need to set enabled/disabled based on ATTR_PG attributes.
+ if (i_dest_target.get() == NULL)
+ {
+ FAPI_DBG("No target link");
+ o_link_is_enabled = false;
+ o_dest_target_node_id = FBC_NODE_ID_0;
+ o_dest_target_chip_id = FBC_CHIP_ID_0;
+ }
+ else
+ {
+ o_link_is_enabled = true;
+
+ // Extract chip/node ID from destination chip
+ FAPI_TRY(p9_fab_smp_get_node_id_attr(i_dest_target,
+ o_dest_target_node_id),
+ "p9_fab_smp_get_node_id_attr() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ FAPI_TRY(p9_fab_smp_get_chip_id_attr(i_dest_target,
+ o_dest_target_chip_id),
+ "p9_fab_smp_get_chip_id_attr() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read PB Link Mode register and extract per-link training delays
+///
+/// @tparam T template parameter, passed in target.
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_link_en Per-link enable values
+/// @param[in] i_link_target Link endpoint targets
+/// @param[out] o_link_delay_local Array of link round trip delay values
+/// (measured by local chip)
+/// @param[out] o_link_delay_remote Array of link round trip delay values
+/// (measured by remote chips)
+/// @param[out] o_link_number_remote Array of link numbers
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode p9_build_smp_get_link_delays(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_link_en[],
+ fapi2::Target<T> i_link_target[],
+ uint16_t o_link_delay_local[],
+ uint16_t o_link_delay_remote[],
+ uint8_t o_link_number_remote[]);
+
+// Specialization for OBUS
+template<>
+fapi2::ReturnCode p9_build_smp_get_link_delays(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_link_en[],
+ fapi2::Target<fapi2::TARGET_TYPE_OBUS> i_link_target[],
+ uint16_t o_link_delay_local[],
+ uint16_t o_link_delay_remote[],
+ uint8_t o_link_number_remote[])
+{
+ FAPI_DBG("OBUS: Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> l_scomData;
+
+ // Link delay values
+ fapi2::buffer<uint64_t> pu_ioe_olink_0123_delay;
+ fapi2::buffer<uint64_t> pu_ioe_olink_4567_delay;
+ fapi2::buffer<uint64_t> l_temp;
+
+ // Read PB Link Mode registers on local chip
+ FAPI_TRY(fapi2::getScom(i_smp_chip.chip->this_chip,
+ PU_IOE_PB_OLINK_DLY_0123_REG,
+ pu_ioe_olink_0123_delay),
+ "OBUS: getScom error on addr 0x%.16llX", PU_IOE_PB_OLINK_DLY_0123_REG);
+
+ FAPI_TRY(fapi2::getScom(i_smp_chip.chip->this_chip,
+ PU_IOE_PB_OLINK_DLY_4567_REG,
+ pu_ioe_olink_4567_delay),
+ "OBUS: getScom error on addr 0x%.16llX", PU_IOE_PB_OLINK_DLY_4567_REG);
+
+ // TODO: RTC 147511 - Update link delay calculation methods
+ // Per Joe, we want to compute the link delay as the average of the
+ // even/odd numbers (same for X link)
+
+ // Extract & return link training delays
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ if (!i_link_en[ll])
+ {
+ o_link_delay_local[ll] = 0xFF; // Even
+ }
+ else
+ {
+ // Select data buffer to get delay values from
+ if (ll < 2)
+ {
+ l_temp = pu_ioe_olink_0123_delay;
+ }
+ else
+ {
+ l_temp = pu_ioe_olink_4567_delay;
+ }
+
+ // Even
+ FAPI_TRY( l_temp.extractToRight(o_link_delay_local[ll],
+ OPTIC_EVEN_LINK_DELAY_START_BIT[ll],
+ LINK_DELAY_BIT_LEN),
+ "OBUS: l_temp.extractToRight() - OBUS/Even returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ // Process remote links
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ if (!i_link_en[ll])
+ {
+ o_link_delay_remote[ll] = 0xFF;
+ }
+ else
+ {
+ uint8_t remote_link_number = 0x0;
+
+ // Determine link number on remote end (equivalent to chiplet #)
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_link_target[ll],
+ remote_link_number),
+ "OBUS: Error querying ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ o_link_number_remote[ll] = remote_link_number;
+
+ // Obtain parent chip target
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procChip;
+ l_procChip =
+ i_link_target[ll].getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ // Read PB Link Mode registers on remote chip
+ FAPI_TRY(fapi2::getScom(l_procChip,
+ PU_IOE_PB_OLINK_DLY_0123_REG,
+ pu_ioe_olink_0123_delay),
+ "OBUS: getScom error on addr 0x%.16llX", PU_IOE_PB_OLINK_DLY_0123_REG);
+
+ FAPI_TRY(fapi2::getScom(l_procChip,
+ PU_IOE_PB_OLINK_DLY_4567_REG,
+ pu_ioe_olink_4567_delay),
+ "OBUS: getScom error on addr 0x%.16llX", PU_IOE_PB_OLINK_DLY_4567_REG);
+
+ // Select data buffer to get delay values from
+ if (remote_link_number < 2)
+ {
+ l_temp = pu_ioe_olink_0123_delay;
+ }
+ else
+ {
+ l_temp = pu_ioe_olink_4567_delay;
+ }
+
+ // Even
+ FAPI_TRY( l_temp.extractToRight(
+ o_link_delay_remote[ll],
+ OPTIC_EVEN_LINK_DELAY_START_BIT[ll],
+ LINK_DELAY_BIT_LEN),
+ "OBUS: l_temp.extractToRight() - OBUS/Even/Remote returns an error, "
+ "l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+ }
+ }
+
+fapi_try_exit:
+ FAPI_DBG("OBUS: End");
+ return fapi2::current_err;
+}
+
+// Specialization for XBUS
+template<>
+fapi2::ReturnCode p9_build_smp_get_link_delays(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_link_en[],
+ fapi2::Target<fapi2::TARGET_TYPE_XBUS> i_link_target[],
+ uint16_t o_link_delay_local[],
+ uint16_t o_link_delay_remote[],
+ uint8_t o_link_number_remote[])
+{
+ FAPI_DBG("XBUS: Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> l_scomData;
+
+ // Link delay values
+ fapi2::buffer<uint64_t> pu_elink_0123_delay;
+ fapi2::buffer<uint64_t> pu_elink_45_delay;
+ fapi2::buffer<uint64_t> l_temp;
+
+ // Read PB Link Mode registers on local chip
+ FAPI_TRY(fapi2::getScom(i_smp_chip.chip->this_chip,
+ PU_PB_ELINK_DLY_0123_REG,
+ pu_elink_0123_delay),
+ "XBUS: getScom error on addr 0x%.16llX", PU_PB_ELINK_DLY_0123_REG);
+
+ FAPI_TRY(fapi2::getScom(i_smp_chip.chip->this_chip,
+ PU_PB_ELINK_DLY_45_REG,
+ pu_elink_45_delay),
+ "XBUS: getScom error on addr 0x%.16llX", PU_PB_ELINK_DLY_45_REG);
+
+ // TODO: RTC 147511 - Update link delay calculation methods
+ // Per Joe, we want to compute the link delay as the average of the
+ // even/odd numbers (same for X link)
+
+ // Extract & return link training delays
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ if (!i_link_en[ll])
+ {
+ o_link_delay_local[ll] = 0xFF; // Even
+ }
+ else
+ {
+ // Select data buffer to get delay values from
+ if (ll < 2)
+ {
+ l_temp = pu_elink_0123_delay;
+ }
+ else
+ {
+ l_temp = pu_elink_45_delay;
+ }
+
+ // Even
+ FAPI_TRY( l_temp.extractToRight(o_link_delay_local[ll],
+ X_EVEN_LINK_DELAY_START_BIT[ll],
+ LINK_DELAY_BIT_LEN),
+ "XBUS: l_temp.extractToRight() - XBUS/Even returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ // Process remote links
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ if (!i_link_en[ll])
+ {
+ o_link_delay_remote[ll] = 0xFF;
+ }
+ else
+ {
+ uint8_t remote_link_number = 0x0;
+
+ // Determine link number on remote end (equivalent to chiplet #)
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_link_target[ll],
+ remote_link_number),
+ "XBUS: Error querying ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ o_link_number_remote[ll] = remote_link_number;
+
+ // Obtain parent chip target
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procChip;
+ l_procChip =
+ i_link_target[ll].getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ // Read PB Link Mode registers on remote chip
+ FAPI_TRY(fapi2::getScom(l_procChip,
+ PU_PB_ELINK_DLY_0123_REG,
+ pu_elink_0123_delay),
+ "XBUS: getScom error on addr 0x%.16llX", PU_PB_ELINK_DLY_0123_REG);
+
+ FAPI_TRY(fapi2::getScom(l_procChip,
+ PU_PB_ELINK_DLY_45_REG,
+ pu_elink_45_delay),
+ "OBUS: getScom error on addr 0x%.16llX", PU_PB_ELINK_DLY_45_REG);
+
+ // Select data buffer to get delay values from
+ if (remote_link_number < 2)
+ {
+ l_temp = pu_elink_0123_delay;
+ }
+ else
+ {
+ l_temp = pu_elink_45_delay;
+ }
+
+ // Even
+ FAPI_TRY( l_temp.extractToRight(
+ o_link_delay_remote[ll],
+ X_EVEN_LINK_DELAY_START_BIT[ll],
+ LINK_DELAY_BIT_LEN),
+ "XBUS: l_temp.extractToRight() - XBUS/Even/Remote returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+fapi_try_exit:
+ FAPI_DBG("XBUS: End");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determine link address/data
+///
+/// @tparam T template parameter, passed in target.
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_link_en Per-link enable values
+/// @param[in] i_link_id Per-link destination chip/node ID values
+/// @param[in] i_link_target Per-link destination targets
+/// @param[out] o_link_addr_dis Per-link address disable values
+/// (true=address only, false=address/data)
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode p9_build_smp_calc_link_setup(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_link_en[],
+ const uint8_t i_link_id[],
+ fapi2::Target<T> i_link_target[],
+ bool o_link_addr_dis[]);
+
+// Specialization for OBUS
+template<>
+fapi2::ReturnCode p9_build_smp_calc_link_setup(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_link_en[],
+ const uint8_t i_link_id[],
+ fapi2::Target<fapi2::TARGET_TYPE_OBUS> i_link_target[],
+ bool o_link_addr_dis[])
+{
+ FAPI_DBG("OBUS: Start");
+ fapi2::ReturnCode l_rc;
+ uint8_t l_idLocal = 0;
+
+ // Mark number of links targeting each ID
+ uint8_t l_idActiveCount[P9_FAB_SMP_NUM_NODE_IDS];
+
+ // Link round trip delay values
+ uint16_t link_delay_local[P9_FAB_SMP_NUM_OPTIC_LINKS];
+ uint16_t link_delay_remote[P9_FAB_SMP_NUM_OPTIC_LINKS];
+ uint8_t link_number_remote[P9_FAB_SMP_NUM_OPTIC_LINKS];
+
+ // Init local arrays
+ for (uint8_t id = 0; id < P9_FAB_SMP_NUM_CHIP_IDS; id++)
+ {
+ l_idActiveCount[id] = 0;
+ }
+
+ // Process all links
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ // Mark link ID
+ if (i_link_en[ll])
+ {
+ l_idActiveCount[i_link_id[ll]]++;
+ }
+
+ // Set default value for link address disable (enable coherency)
+ o_link_addr_dis[ll] = false;
+ }
+
+ // Figure out if link is to carry data only (Address disabled)
+ for (uint8_t l_id = 0; l_id < P9_FAB_SMP_NUM_NODE_IDS; l_id++)
+ {
+ // Skip if not active
+ if (!l_idActiveCount[l_id])
+ {
+ continue;
+ }
+
+ // Flip default value for link address disable
+ // (disable coherency)
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ if (i_link_en[ll])
+ {
+ o_link_addr_dis[ll] = true;
+ }
+ }
+
+ // Select link with the lowest round trip latency value
+ // to carry coherency
+ FAPI_TRY(p9_build_smp_get_link_delays(i_smp_chip,
+ i_link_en,
+ i_link_target,
+ link_delay_local,
+ link_delay_remote,
+ link_number_remote),
+ "p9_build_smp_get_link_delays() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Debug trace
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ FAPI_DBG("Link[%d]):");
+ FAPI_DBG(" link_delay_local: %d, link_delay_remote: %d, "
+ "link_number_remote: %d", ll, link_delay_local[ll],
+ link_delay_remote[ll], link_number_remote[ll]);
+ }
+
+ // Sum local/remote delay factors & scan for smallest value
+ uint32_t link_delay_total[P9_FAB_SMP_NUM_OPTIC_LINKS];
+ uint8_t coherent_link_index = 0xFF;
+ uint32_t coherent_link_delay = 0xFFFFFFFF;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ link_delay_total[ll] = link_delay_local[ll] + link_delay_remote[ll];
+
+ if ( i_link_en[ll] &&
+ (link_delay_total[ll] < coherent_link_delay) )
+ {
+ coherent_link_delay = link_delay_total[ll];
+ FAPI_DBG("Setting coherent_link_delay = %d", coherent_link_delay);
+ }
+ }
+
+ // Ties must be broken consistently on both connected chips
+ // search if a tie has occurred
+ uint8_t matches = 0;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ if (i_link_en[ll] &&
+ (link_delay_total[ll] == coherent_link_delay))
+ {
+ matches++;
+ coherent_link_index = ll;
+ }
+ }
+
+ // If no ties, we're done
+ // else, break tie
+
+ // Select link with lowest link number on chip with smaller ID
+ // (chip ID if X links, node ID if A links)
+ l_idLocal = i_smp_chip.node_id;
+
+ if (matches != 1)
+ {
+ FAPI_DBG("Breaking tie");
+
+ if (l_idLocal < l_id)
+ {
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ if (i_link_en[ll] &&
+ (link_delay_total[ll] == coherent_link_delay))
+ {
+ coherent_link_index = ll;
+ break;
+ }
+ }
+
+ FAPI_DBG("Selecting coherent link = link %d based on this chip (%d)",
+ coherent_link_index, l_idLocal);
+ }
+ else
+ {
+ uint8_t lowest_remote_link_number = 0xFF;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ if ((i_link_en[ll]) &&
+ (link_delay_total[ll] == coherent_link_delay) &&
+ (link_number_remote[ll] < lowest_remote_link_number))
+ {
+ lowest_remote_link_number = link_number_remote[ll];
+ coherent_link_index = ll;
+ }
+ }
+
+ FAPI_DBG("Selecting coherent link = linkd %d based on remote chip ID (%d)",
+ coherent_link_index, l_id);
+ }
+ }
+
+ o_link_addr_dis[coherent_link_index] = false;
+ }
+
+fapi_try_exit:
+ FAPI_DBG("OBUS: End");
+ return fapi2::current_err;
+}
+
+// Specialization for XBUS
+template<>
+fapi2::ReturnCode p9_build_smp_calc_link_setup(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_link_en[],
+ const uint8_t i_link_id[],
+ fapi2::Target<fapi2::TARGET_TYPE_XBUS> i_link_target[],
+ bool o_link_addr_dis[])
+{
+ FAPI_DBG("XBUS: Start");
+ fapi2::ReturnCode l_rc;
+ uint8_t l_idLocal = 0;
+
+ // Mark number of links targeting each ID
+ uint8_t l_idActiveCount[P9_FAB_SMP_NUM_CHIP_IDS];
+
+ // Link round trip delay values
+ uint16_t link_delay_local[P9_FAB_SMP_NUM_X_LINKS];
+ uint16_t link_delay_remote[P9_FAB_SMP_NUM_X_LINKS];
+ uint8_t link_number_remote[P9_FAB_SMP_NUM_X_LINKS];
+
+ // Init local arrays
+ for (uint8_t id = 0; id < P9_FAB_SMP_NUM_X_LINKS; id++)
+ {
+ l_idActiveCount[id] = 0;
+ }
+
+ // Process all links
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ // Mark link ID
+ if (i_link_en[ll])
+ {
+ l_idActiveCount[i_link_id[ll]]++;
+ }
+
+ // Set default value for link address disable (enable coherency)
+ o_link_addr_dis[ll] = false;
+ }
+
+ // Figure out if link is to carry data only (ADDR_DIS)
+ for (uint8_t l_id = 0; l_id < P9_FAB_SMP_NUM_CHIP_IDS; l_id++)
+ {
+ // Skip if not active
+ if (!l_idActiveCount[l_id])
+ {
+ continue;
+ }
+
+ // Flip default value for link address disable
+ // (disable coherency)
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ if (i_link_en[ll])
+ {
+ o_link_addr_dis[ll] = true;
+ }
+ }
+
+ // Select link with the lowest round trip latency value
+ // to carry coherency
+ FAPI_TRY(p9_build_smp_get_link_delays(i_smp_chip,
+ i_link_en,
+ i_link_target,
+ link_delay_local,
+ link_delay_remote,
+ link_number_remote),
+ "p9_build_smp_get_link_delays() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Debug trace
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ FAPI_DBG("Link[%d]):");
+ FAPI_DBG(" link_delay_local: %d, link_delay_remote: %d, "
+ "link_number_remote: %d", ll, link_delay_local[ll],
+ link_delay_remote[ll], link_number_remote[ll]);
+ }
+
+ // Sum local/remote delay factors & scan for smallest value
+ uint32_t link_delay_total[P9_FAB_SMP_NUM_X_LINKS];
+ uint8_t coherent_link_index = 0xFF;
+ uint32_t coherent_link_delay = 0xFFFFFFFF;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ link_delay_total[ll] = link_delay_local[ll] + link_delay_remote[ll];
+
+ if ( i_link_en[ll] &&
+ (link_delay_total[ll] < coherent_link_delay) )
+ {
+ coherent_link_delay = link_delay_total[ll];
+ FAPI_DBG("Setting coherent_link_delay = %d", coherent_link_delay);
+ }
+ }
+
+ // Ties must be broken consistently on both connected chips
+ // search if a tie has occurred
+ uint8_t matches = 0;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ if (i_link_en[ll] &&
+ (link_delay_total[ll] == coherent_link_delay))
+ {
+ matches++;
+ coherent_link_index = ll;
+ }
+ }
+
+ // If no ties, we're done
+ // else, break tie
+
+ // Select link with lowest link number on chip with smaller ID
+ // (chip ID if X links, node ID if A links)
+ l_idLocal = i_smp_chip.chip_id;
+
+ if (matches != 1)
+ {
+ FAPI_DBG("Breaking tie");
+
+ if (l_idLocal < l_id)
+ {
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ if (i_link_en[ll] &&
+ (link_delay_total[ll] == coherent_link_delay))
+ {
+ coherent_link_index = ll;
+ break;
+ }
+ }
+
+ FAPI_DBG("Selecting coherent link = link %d based on this chip (%d)",
+ coherent_link_index, l_idLocal);
+ }
+ else
+ {
+ uint8_t lowest_remote_link_number = 0xFF;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ if ((i_link_en[ll]) &&
+ (link_delay_total[ll] == coherent_link_delay) &&
+ (link_number_remote[ll] < lowest_remote_link_number))
+ {
+ lowest_remote_link_number = link_number_remote[ll];
+ coherent_link_index = ll;
+ }
+ }
+
+ FAPI_DBG("Selecting coherent link = linkd %d based on remote chip ID (%d)",
+ coherent_link_index, l_id);
+ }
+ }
+
+ o_link_addr_dis[coherent_link_index] = false;
+ }
+
+fapi_try_exit:
+ FAPI_DBG("XBUS: End");
+ return fapi2::current_err;
+}
+
+extern "C" {
+
+// See doxygen in header file
+ fapi2::ReturnCode p9_build_smp_get_hotplug_curr_reg(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_hp_not_hpx,
+ fapi2::buffer<uint64_t>& o_data)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> l_scomData;
+
+ // Check consistency of west/center/east register copies
+ for (uint8_t rr = 0; rr < P9_BUILD_SMP_NUM_SHADOWS; rr++)
+ {
+ // Get current (working) register
+ uint64_t l_reg = i_hp_not_hpx ? PB_HP_MODE_CURR_SHADOWS[rr] :
+ PB_HPX_MODE_CURR_SHADOWS[rr];
+
+ FAPI_TRY(fapi2::getScom(i_smp_chip.chip->this_chip, l_reg, l_scomData),
+ "getScom returns error: Addr 0x%016llX, l_rc 0x%.8X",
+ l_reg, (uint64_t)fapi2::current_err);
+
+ // Raise error if shadow copies aren't equal
+ FAPI_ASSERT( (rr == 0) || (l_scomData == o_data),
+ fapi2::PROC_BUILD_SMP_HOTPLUG_SHADOW_ERR()
+ .set_ADDRESS0((i_hp_not_hpx) ? (PB_HP_MODE_CURR_SHADOWS[rr - 1]) :
+ (PB_HPX_MODE_CURR_SHADOWS[rr - 1])
+ )
+ .set_ADDRESS1(l_reg)
+ .set_DATA0(o_data)
+ .set_DATA1(l_scomData),
+ "Shadow copies are not equivalent");
+
+ // Set output (will be used to compare with next HW read)
+ o_data = l_scomData;
+ }
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+///
+/// @brief Program PB Hotplug Mode register
+///
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_smp Structure encapsulating SMP topology
+/// @param[in] i_set_curr Set CURR register set?
+/// @param[in] i_set_next Set NEXT register set?
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_set_pb_hp_mode(
+ const p9_build_smp_chip& i_smp_chip,
+ const p9_build_smp_system& i_smp,
+ const bool i_set_curr,
+ const bool i_set_next)
+ {
+
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> l_scomData;
+
+ // Set of per-link destination chip targets
+ fapi2::Target<fapi2::TARGET_TYPE_OBUS> o_target[P9_FAB_SMP_NUM_OPTIC_LINKS];
+ // Per-link enables
+ bool o_en[P9_FAB_SMP_NUM_OPTIC_LINKS];
+ // Per-link destination IDs
+ uint8_t o_id[P9_FAB_SMP_NUM_OPTIC_LINKS];
+ // Per-link address disable values
+ bool o_addr_dis[P9_FAB_SMP_NUM_OPTIC_LINKS];
+
+ // TODO: RTC 147511 - Need to handle PCIE link
+
+ // Process all optic links
+ o_target[0] = i_smp_chip.chip->o0_chip;
+ o_target[1] = i_smp_chip.chip->o1_chip;
+ o_target[2] = i_smp_chip.chip->o2_chip;
+ o_target[3] = i_smp_chip.chip->o2_chip;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_OPTIC_LINKS; ll++)
+ {
+ // Determine link enable/ID
+ p9_fab_smp_node_id dest_node_id;
+ p9_fab_smp_chip_id dest_chip_id;
+ FAPI_TRY(p9_build_smp_query_link_state(i_smp_chip,
+ ll,
+ o_target[ll],
+ o_en[ll],
+ dest_node_id,
+ dest_chip_id),
+ "p9_build_smp_query_link_state() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ o_id[ll] = (uint8_t) dest_node_id;
+ }
+
+ // Determine address/data assignents
+ // link command rates (A)
+ if (i_smp_chip.o_enabled)
+ {
+ FAPI_TRY(p9_build_smp_calc_link_setup(i_smp_chip,
+ o_en,
+ o_id,
+ o_target,
+ o_addr_dis),
+ "p9_build_smp_calc_link_setup() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+ // Set attributes
+ if (i_smp_chip.smpOpticsMode ==
+ fapi2::ENUM_ATTR_PROC_FABRIC_SMP_OPTICS_MODE_OPTICS_IS_X_BUS)
+ {
+ uint8_t l_x_address_dis[P9_FAB_SMP_NUM_X_LINKS +
+ P9_FAB_SMP_NUM_OPTIC_LINKS];
+
+ // Optic is XBUS, write to X-LINK attribute
+
+ // Read current values to preserve the first 3 values from XBUS
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_X_ADDR_DIS,
+ i_smp_chip.chip->this_chip,
+ l_x_address_dis),
+ "Error getting ATTR_PROC_FABRIC_X_ADDR_DIS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Store optic addr_dis starting at index 3
+ for (uint8_t ii = 0; ii < P9_FAB_SMP_NUM_OPTIC_LINKS; ii++)
+ {
+ l_x_address_dis[ii + P9_FAB_SMP_NUM_X_LINKS] =
+ o_addr_dis[ii] ? 1 : 0;
+ }
+
+ // Write attribute back
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_FABRIC_X_ADDR_DIS,
+ i_smp_chip.chip->this_chip,
+ l_x_address_dis),
+ "Error setting ATTR_PROC_FABRIC_X_ADDR_DIS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ else
+ {
+ uint8_t l_a_address_dis[P9_FAB_SMP_NUM_OPTIC_LINKS];
+
+ for (uint8_t ii = 0; ii < P9_FAB_SMP_NUM_OPTIC_LINKS; ii++)
+ {
+ l_a_address_dis[ii] = o_addr_dis[ii] ? 1 : 0;
+ }
+
+ // Optic is ABUS, write to A-LINK attribute
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_FABRIC_A_ADDR_DIS,
+ i_smp_chip.chip->this_chip,
+ l_a_address_dis),
+ "Error setting ATTR_PROC_FABRIC_A_ADDR_DIS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+ // TODO: RTC 147511 - Call initfile
+ // Call initfile when available to re-program slave fabrics
+#if 0
+
+ // Run initfile to set CURR (OBUS)
+ if (i_set_curr)
+ {
+ FAPI_TRY(p9_set_curr_initfile(),
+ "p9_set_curr_initfile() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+ // Run initfile to set NEXT (OBUS)
+ if (i_set_next)
+ {
+ FAPI_TRY(p9_set_next_initfile(),
+ "p9_set_next_initfile() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+#endif
+
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+///
+/// @brief Program PB Hotplug Extension Mode register
+///
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_smp Structure encapsulating SMP topology
+/// @param[in] i_set_curr Set CURR register set?
+/// @param[in] i_set_next Set NEXT register set?
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_set_pb_hpx_mode(
+ const p9_build_smp_chip& i_smp_chip,
+ const p9_build_smp_system& i_smp,
+ const bool i_set_curr,
+ const bool i_set_next)
+ {
+
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> l_scomData;
+
+ // set of per-link destination chip targets
+ fapi2::Target<fapi2::TARGET_TYPE_XBUS> x_target[P9_FAB_SMP_NUM_X_LINKS];
+ // Per-link enables
+ bool x_en[P9_FAB_SMP_NUM_X_LINKS];
+ // Per-link destination IDs
+ uint8_t x_id[P9_FAB_SMP_NUM_X_LINKS];
+ // Per-link address disable values
+ bool x_addr_dis[P9_FAB_SMP_NUM_X_LINKS];
+
+ // Process all links
+ x_target[0] = i_smp_chip.chip->x0_chip;
+ x_target[1] = i_smp_chip.chip->x1_chip;
+ x_target[2] = i_smp_chip.chip->x2_chip;
+
+ for (uint8_t ll = 0; ll < P9_FAB_SMP_NUM_X_LINKS; ll++)
+ {
+ // Determine link enable/ID
+ p9_fab_smp_node_id dest_node_id;
+ p9_fab_smp_chip_id dest_chip_id;
+ FAPI_TRY(p9_build_smp_query_link_state(i_smp_chip,
+ ll,
+ x_target[ll],
+ x_en[ll],
+ dest_node_id,
+ dest_chip_id),
+ "p9_build_smp_query_link_state() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ x_id[ll] = (uint8_t) dest_chip_id;
+ }
+
+ // Determine address/data assignents
+ if (i_smp_chip.x_enabled)
+ {
+ FAPI_TRY(p9_build_smp_calc_link_setup(i_smp_chip,
+ x_en,
+ x_id,
+ x_target,
+ x_addr_dis),
+ "p9_build_smp_calc_link_setup() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+ // Set attributes
+ uint8_t l_x_address_dis[P9_FAB_SMP_NUM_X_LINKS +
+ P9_FAB_SMP_NUM_OPTIC_LINKS];
+
+ // Read current values to preserve the settings for OBUS
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_X_ADDR_DIS,
+ i_smp_chip.chip->this_chip,
+ l_x_address_dis),
+ "Error getting ATTR_PROC_FABRIC_X_ADDR_DIS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Store at first 3 indexes for XBUS targets
+ for (uint8_t ii = 0; ii < P9_FAB_SMP_NUM_X_LINKS; ii++)
+ {
+ l_x_address_dis[ii] = x_addr_dis[ii] ? 1 : 0;
+ }
+
+ // Write attribute back
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_FABRIC_X_ADDR_DIS,
+ i_smp_chip.chip->this_chip,
+ l_x_address_dis),
+ "Error setting ATTR_PROC_FABRIC_X_ADDR_DIS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // TODO: RTC 147511 - Call initfile
+ // Call initfile when available to re-program slave fabrics
+#if 0
+
+ // Run initfile to set CURR (XBUS)
+ if (i_set_curr)
+ {
+ FAPI_TRY(p9_set_curr_initfile(),
+ "p9_build_smp_set_pb_hp_mode: p9_set_curr_initfile() "
+ "returns an error, l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+ }
+
+ // Run initfile to set NEXT (XBUS)
+ if (i_set_next)
+ {
+ FAPI_TRY(p9_set_next_initfile(),
+ "p9_build_smp_set_pb_hp_mode: p9_set_next_initfile() "
+ "returns an error, l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+ }
+
+#endif
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+
+///
+/// @brief Utility function to program set of PB hotplug registers
+///
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_curr_not_next Choose CURR/NEXT register set (true=CURR,
+/// false=NEXT)
+/// @param[in] i_hp_not_hpx Structure encapsulating SMP topology
+/// @param[in] i_set_curr Choose HP/HPX register set (true=HP,
+/// false=HPX)
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_set_hotplug_reg(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_curr_not_next,
+ const bool i_hp_not_hpx,
+ const fapi2::buffer<uint64_t> i_data)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ uint64_t l_scomAddr;
+
+ // write west/center/east register copies
+ for (uint8_t rr = 0; rr < P9_BUILD_SMP_NUM_SHADOWS; rr++)
+ {
+ // Set target scom address based on input parameters
+ if (i_curr_not_next)
+ {
+ if (i_hp_not_hpx)
+ {
+ l_scomAddr = PB_HP_MODE_CURR_SHADOWS[rr];
+ }
+ else
+ {
+ l_scomAddr = PB_HPX_MODE_CURR_SHADOWS[rr];
+ }
+ }
+ else
+ {
+ if (i_hp_not_hpx)
+ {
+ l_scomAddr = PB_HP_MODE_NEXT_SHADOWS[rr];
+ }
+ else
+ {
+ l_scomAddr = PB_HPX_MODE_NEXT_SHADOWS[rr];
+ }
+ }
+
+ // Write register
+ FAPI_TRY(fapi2::putScom(i_smp_chip.chip->this_chip, l_scomAddr, i_data),
+ "putScom error, addr 0x%.16llX", l_scomAddr);
+ }
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+///
+/// @brief Reset (copy CURR->NEXT) PB Hotplug Mode/Mode Extension register
+///
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_hp_not_hpx Structure encapsulating SMP topology
+/// @param[in] i_set_curr Choose HP/HPX register set (true=HP,
+/// false=HPX)
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_reset_hotplug_next_reg(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_hp_not_hpx)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+ fapi2::buffer<uint64_t> l_scomData;
+
+ // Read CURR state
+ FAPI_TRY(p9_build_smp_get_hotplug_curr_reg(i_smp_chip,
+ i_hp_not_hpx,
+ l_scomData),
+ "p9_build_smp_get_hotplug_curr_reg() Returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Write NEXT state
+ FAPI_TRY(p9_build_smp_set_hotplug_reg(i_smp_chip,
+ false,
+ i_hp_not_hpx,
+ l_scomData),
+ "p9_build_smp_set_hotplug_reg() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+// NOTE: see comments above function prototype in header
+ fapi2::ReturnCode p9_build_smp_set_fbc_ab(p9_build_smp_system& i_smp,
+ const p9_build_smp_operation i_op)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+
+ // Chip/Node map iterators
+ std::map<p9_fab_smp_node_id, p9_build_smp_node>::iterator n_iter;
+ std::map<p9_fab_smp_chip_id, p9_build_smp_chip>::iterator p_iter;
+
+ // Quiesce 'slave' fabrics in preparation for joining
+ // PHASE1 -> quiesce all chips except the chip which is the new fabric master
+ // PHASE2 -> quiesce all drawers except the drawer containing the new fabric master
+ FAPI_TRY(p9_build_smp_quiesce_pb(i_smp, i_op),
+ "p9_build_smp_quiesce_pb() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Program CURR register set only for chips which were just quiesced
+ // Program NEXT register set for all chips
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+ FAPI_TRY(p9_build_smp_set_pb_hp_mode(
+ p_iter->second, i_smp,
+ p_iter->second.quiesced_next, // Set CURR
+ true), // Set NEXT
+ "p9_build_smp_set_pb_hp_mode() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ FAPI_TRY(p9_build_smp_set_pb_hpx_mode(
+ p_iter->second, i_smp,
+ p_iter->second.quiesced_next, // Set CURR
+ true), // Set NEXT
+ "p9_build_smp_set_pb_hpx_mode() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ // Issue switch AB reconfiguration from chip designated as new master
+ // (which is guaranteed to be a master now)
+ FAPI_TRY(p9_build_smp_switch_ab(i_smp, i_op),
+ "p9_build_smp_switch_ab() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Reset NEXT register set (copy CURR->NEXT) for all chips
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+
+ FAPI_TRY(p9_build_smp_reset_hotplug_next_reg(p_iter->second, true),
+ "p9_build_smp_reset_hotplug_next_reg(true) returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ FAPI_TRY(p9_build_smp_reset_hotplug_next_reg(p_iter->second, false),
+ "p9_build_smp_reset_hotplug_next_reg(false) returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+ }
+
+
+} // extern "C"
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.H b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.H
new file mode 100644
index 000000000..3e74d663c
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.H
@@ -0,0 +1,152 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/nest/p9_build_smp_fbc_ab.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_build_smp_fbc_ab.H
+/// @brief Fabric configuration (hotplug, AB) functions.
+///
+/// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
+/// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+/// *HWP Team: Nest
+/// *HWP Level: 2
+/// *HWP Consumed by: HB,FSP
+///
+
+#ifndef _P9_BUILD_SMP_FBC_AB_H_
+#define _P9_BUILD_SMP_FBC_AB_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <p9_build_smp.H>
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+// PB Hotplug Mode register field/bit definitions
+const uint32_t PB_HP_MODE_MASTER_CHIP_BIT = 0;
+const uint32_t PB_HP_MODE_CHG_RATE_GP_MASTER_BIT = 2;
+
+// TODO: RTC 147511 - Use SCOM register names from p9_misc_scom_addresses.H
+// Remove the reg addresses defined below and use the ones in
+// p9_misc_scom_addresses.H when available.
+
+// HP
+const uint64_t PB_HP_MODE_CURR_WEST = 0x0501180C;
+const uint64_t PB_HP_MODE_CURR_CENT = 0x05011C0C;
+const uint64_t PB_HP_MODE_CURR_EAST = 0x0501200C;
+const uint64_t PB_HP_MODE_CURR_SHADOWS[P9_BUILD_SMP_NUM_SHADOWS] =
+{
+ PB_HP_MODE_CURR_WEST,
+ PB_HP_MODE_CURR_CENT,
+ PB_HP_MODE_CURR_EAST
+};
+
+const uint64_t PB_HP_MODE_NEXT_WEST = 0x0501180B;
+const uint64_t PB_HP_MODE_NEXT_CENT = 0x05011C0B;
+const uint64_t PB_HP_MODE_NEXT_EAST = 0x0501200B;
+const uint32_t PB_HP_MODE_NEXT_SHADOWS[P9_BUILD_SMP_NUM_SHADOWS] =
+{
+ PB_HP_MODE_NEXT_WEST,
+ PB_HP_MODE_NEXT_CENT,
+ PB_HP_MODE_NEXT_EAST
+};
+
+// HPX
+const uint64_t PB_HPX_MODE_CURR_WEST = 0x05011810;
+const uint64_t PB_HPX_MODE_CURR_CENT = 0x05011C10;
+const uint64_t PB_HPX_MODE_CURR_EAST = 0x05012010;
+const uint32_t PB_HPX_MODE_CURR_SHADOWS[P9_BUILD_SMP_NUM_SHADOWS] =
+{
+ PB_HPX_MODE_CURR_WEST,
+ PB_HPX_MODE_CURR_CENT,
+ PB_HPX_MODE_CURR_EAST
+};
+
+const uint64_t PB_HPX_MODE_NEXT_WEST = 0x0501180F;
+const uint64_t PB_HPX_MODE_NEXT_CENT = 0x05011C0F;
+const uint64_t PB_HPX_MODE_NEXT_EAST = 0x0501200F;
+const uint32_t PB_HPX_MODE_NEXT_SHADOWS[P9_BUILD_SMP_NUM_SHADOWS] =
+{
+ PB_HPX_MODE_NEXT_WEST,
+ PB_HPX_MODE_NEXT_CENT,
+ PB_HPX_MODE_NEXT_EAST
+};
+
+//------------------------------------------------------------------------------
+// Function definitions
+//------------------------------------------------------------------------------
+///
+/// @brief Determine parameters of link/destination chip
+///
+/// @tparam T template parameter, passed in target.
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// @param[in] i_source_link_id Link identifier for FFDC
+/// @param[in] i_dest_target Destination link endpoint target
+/// @param[out] o_link_is_enabled true=link enabled, false=link disabled
+/// @param[out] o_dest_target_node_id Node ID of destination chip
+/// @param[out] o_dest_target_chip_id Chip ID of destination chip
+///
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode p9_build_smp_query_link_state(
+ const p9_build_smp_chip& i_smp_chip,
+ const uint8_t i_source_link_id,
+ const fapi2::Target<T>& i_dest_target,
+ bool& o_link_is_enabled,
+ p9_fab_smp_node_id& o_dest_target_node_id,
+ p9_fab_smp_chip_id& o_dest_target_chip_id);
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+// Function prototypes
+//------------------------------------------------------------------------------
+
+///
+/// @brief Utility function to read set of PB CURR hotplug registers
+///
+/// @param[in] i_smp_chip Structure encapsulating single chip in SMP
+/// topology
+/// @param[in] i_hp_not_hpx Choose HP/HPX register set (true=HP, false=HPX)
+/// @param[out] o_data Data buffer containing read data
+///
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_get_hotplug_curr_reg(
+ const p9_build_smp_chip& i_smp_chip,
+ const bool i_hp_not_hpx,
+ fapi2::buffer<uint64_t>& o_data);
+
+
+///
+/// @brief Program fabric configuration register (hotplug, A/B set)
+///
+/// @param[in] i_smp Structure encapsulating SMP topology
+/// @param[in] i_op Enumerated type representing SMP build phase
+///
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_set_fbc_ab(p9_build_smp_system& i_smp,
+ const p9_build_smp_operation i_op);
+
+} // extern "C"
+
+#endif // _P9_BUILD_SMP_FBC_AB_H_
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.C b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.C
new file mode 100644
index 000000000..d6f88053f
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.C
@@ -0,0 +1,103 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_build_smp_fbc_cd.C
+/// @brief Fabric configuration (hotplug, CD) functions
+///
+/// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
+/// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+/// *HWP Team: Nest
+/// *HWP Level: 2
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <p9_build_smp_fbc_cd.H>
+#include <p9_build_smp_adu.H>
+
+extern "C" {
+
+
+//------------------------------------------------------------------------------
+// Structure definitions
+//------------------------------------------------------------------------------
+
+// structure encapsulating serial configuration load programming
+ struct p9_build_smp_sconfig_def
+ {
+ uint8_t select; // ID/select for chain
+ uint8_t length; // number of bits to load
+ bool use_slow_clock; // use 16:1 slow clock? (EX)
+ bool use_shadow[P9_BUILD_SMP_NUM_SHADOWS]; // define which shadows to set
+ };
+
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Function definitions
+//------------------------------------------------------------------------------
+
+// NOTE: see comments above function prototype in header
+ fapi2::ReturnCode p9_build_smp_set_fbc_cd(p9_build_smp_system& i_smp)
+ {
+ FAPI_DBG("Start");
+ fapi2::ReturnCode l_rc;
+
+ // Chip/Node map iterators
+ std::map<p9_fab_smp_node_id, p9_build_smp_node>::iterator n_iter;
+ std::map<p9_fab_smp_chip_id, p9_build_smp_chip>::iterator p_iter;
+
+ for (n_iter = i_smp.nodes.begin();
+ n_iter != i_smp.nodes.end();
+ ++n_iter)
+ {
+ for (p_iter = n_iter->second.chips.begin();
+ p_iter != n_iter->second.chips.end();
+ ++p_iter)
+ {
+
+ // TODO: RTC 147511 - Call initfile
+ // Call initfile when available to program center/east/west chains
+ FAPI_DBG("Invoking initfile %s",
+ "TODO RTC 147511 - Replace with initfile name here");
+#if 0
+ // Run initfile to program chains
+ FAPI_TRY(p9_build_smp_set_sconfig(p_iter->second),
+ "p9_build_smp_set_sconfig() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+#endif
+
+ // Issue single switch CD to force all updates to occur
+ FAPI_TRY(p9_build_smp_switch_cd(p_iter->second, i_smp),
+ "p9_build_smp_switch_cd returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+ }
+
+ fapi_try_exit:
+ FAPI_INF("End");
+ return fapi2::current_err;
+ }
+
+} // extern "C"
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.H b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.H
new file mode 100644
index 000000000..d1d2ab054
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.H
@@ -0,0 +1,66 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/nest/p9_build_smp_fbc_cd.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_build_smp_fbc_cd.H
+/// @brief Fabric configuration (hotplug, CD) functions
+///
+/// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
+/// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+/// *HWP Team: Nest
+/// *HWP Level: 2
+///
+
+#ifndef _P9_BUILD_SMP_FBC_CD_H_
+#define _P9_BUILD_SMP_FBC_CD_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <p9_build_smp.H>
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+// TODO: RTC 147511 - Use SCOM register names from p9_misc_scom_addresses.H
+// Remove the reg addresses defined below and use the ones in
+// p9_misc_scom_addresses.H when available.
+const uint64_t PB_SCONFIG_LOAD_WEST = 0x05011811;
+const uint64_t PB_SCONFIG_LOAD_CENT = 0x05011C11;
+const uint64_t PB_SCONFIG_LOAD_EAST = 0x05012011;
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+// Function prototypes
+//------------------------------------------------------------------------------
+
+///
+/// @brief Program fabric configuration register (hotplug, C/D set)
+/// @param[in] i_smp Structure encapsulating SMP topology
+///
+/// @return fapi2:ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode p9_build_smp_set_fbc_cd(p9_build_smp_system& i_smp);
+
+
+} // extern "C"
+
+#endif // _P9_BUILD_SMP_FBC_CD_H_
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_build_smp_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_build_smp_errors.xml
new file mode 100644
index 000000000..ee1472c6d
--- /dev/null
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_build_smp_errors.xml
@@ -0,0 +1,233 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: chips/p9/procedures/xml/error_info/p9_build_smp_errors.xml $ -->
+<!-- -->
+<!-- IBM CONFIDENTIAL -->
+<!-- -->
+<!-- EKB Project -->
+<!-- -->
+<!-- COPYRIGHT 2015,2016 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- The source code for this program is not published or otherwise -->
+<!-- divested of its trade secrets, irrespective of what has been -->
+<!-- deposited with the U.S. Copyright Office. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<!-- File: p9_build_smp_errors.xml. -->
+<!-- Error definitions for p9_build_smp HWP. -->
+
+<hwpErrors>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_CORE_FREQ_RANGE_ERR</rc>
+ <description>Invalid relationship between ceiling/nominal/floor core frequency attributes.</description>
+ <ffdc>FREQ_CORE_CEILING</ffdc>
+ <ffdc>FREQ_CORE_NOM</ffdc>
+ <ffdc>FREQ_CORE_FLOOR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_P9_FAB_SMP_PUMP_MODE_ATTR_ERR</rc>
+ <description>Invalid definition for fabric pump mode attribute value.</description>
+ <ffdc>ATTR_DATA</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_P9_FAB_SMP_EPSILON_TABLE_TYPE_ATTR_ERR</rc>
+ <description>Invalid definition for epsilon table type attribute value.</description>
+ <ffdc>ATTR_DATA</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_CORE_FLOOR_FREQ_RATIO_ERR</rc>
+ <description>Unsupported core floor to PB frequency ratio.</description>
+ <ffdc>FREQ_PB</ffdc>
+ <ffdc>FREQ_CORE_FLOOR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_CORE_CEILING_FREQ_RATIO_ERR</rc>
+ <description>Unsupported core ceiling to PB frequency ratio.</description>
+ <ffdc>FREQ_PB</ffdc>
+ <ffdc>FREQ_CORE_CEILING</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_FAB_SMP_FABRIC_GROUP_ID_ATTR_ERR</rc>
+ <description>Invalid definition for fabric group ID attribute value.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>ATTR_DATA</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_FAB_SMP_FABRIC_CHIP_ID_ATTR_ERR</rc>
+ <description>Invalid definition for fabric chip ID attribute value.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>ATTR_DATA</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_NODE_ADD_INTERNAL_ERR</rc>
+ <description>Internal Error. Error encountered adding node to SMP structure.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>NODE_ID</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_DUPLICATE_FABRIC_ID_ERR</rc>
+ <description>Multiple chips found with identifcal fabric node/chip ID attribute values.</description>
+ <ffdc>TARGET1</ffdc>
+ <ffdc>TARGET2</ffdc>
+ <ffdc>NODE_ID</ffdc>
+ <ffdc>CHIP_ID</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_HOTPLUG_SHADOW_ERR</rc>
+ <description>Inconsistent state in hotplug (CURR) shadow copies.</description>
+ <ffdc>ADDRESS0</ffdc>
+ <ffdc>ADDRESS1</ffdc>
+ <ffdc>DATA0</ffdc>
+ <ffdc>DATA1</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_INVALID_OPERATION_ERR</rc>
+ <description>Unsupported SMP build operation presented.</description>
+ <ffdc>OP</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_MASTER_DESIGNATION_ERR</rc>
+ <description>Node or system master chip designation error.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>OP</ffdc>
+ <ffdc>MASTER_CHIP_SYS_CURR</ffdc>
+ <ffdc>MASTER_CHIP_NODE_CURR</ffdc>
+ <ffdc>MASTER_CHIP_SYS_NEXT</ffdc>
+ <ffdc>MASTER_CHIP_NODE_NEXT</ffdc>
+ <ffdc>SYS_RECONFIG_MASTER_SET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_NO_MASTER_SPECIFIED_ERR</rc>
+ <description>Input parameters do not specify a new fabric system master.</description>
+ <ffdc>OP</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_INVALID_TOPOLOGY</rc>
+ <description>Invalid fabric topology specified by input parameters.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>A_CONNECTIONS_OK</ffdc>
+ <ffdc>A_CONNECTED_NODE_IDS</ffdc>
+ <ffdc>X_CONNECTIONS_OK</ffdc>
+ <ffdc>X_CONNECTED_CHIP_IDS</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_EPSILON_INVALID_TABLE_ERR</rc>
+ <description>Invalid epsilon table type or content detected.</description>
+ <ffdc>TABLE_TYPE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_EPSILON_RANGE_ERR</rc>
+ <description>Target epsilon value exceeds maximum value supported by HW capabilities.</description>
+ <ffdc>VALUE</ffdc>
+ <ffdc>MAX_HW_VALUE</ffdc>
+ <ffdc>UNIT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_PACING_RATE_TABLE_ERR</rc>
+ <description>Command rate pacing table lookup error.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>GROUP_SIZE</ffdc>
+ <ffdc>NODE_ID</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PROC_BUILD_SMP_INVALID_GROUP_SIZE_ERR</rc>
+ <description>Invalid chips per group configuration detected.</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>GROUP_SIZE</ffdc>
+ <ffdc>NODE_ID</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+</hwpErrors>
OpenPOWER on IntegriCloud