From 3d6217acec3cc424dc631b39b61e8e0eac8406ed Mon Sep 17 00:00:00 2001 From: Thi Tran Date: Fri, 31 Jul 2015 15:35:30 -0500 Subject: SW316014: INITPROC: updates to implement SBE interrupt service CMVC-Coreq: 968951 CQ:SW316014 Change-Id: I31c015962f39342d0d1d9d575fd0c4569496918c Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19475 Reviewed-by: Thi N. Tran Tested-by: Thi N. Tran Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19478 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: A. Patrick Williams III --- src/usr/devtree/bld_devtree.C | 56 +- .../p8_slw_build/p8_delta_scan_rw.h | 22 +- .../p8_slw_build/p8_xip_customize.C | 1230 ++++++++++++++++++-- .../proc_mailbox_utils/p8_mailbox_utils.C | 39 +- src/usr/hwpf/hwp/core_activate/core_activate.C | 8 +- src/usr/hwpf/hwp/core_activate/makefile | 3 +- .../proc_sbe_intr_service.H | 39 + .../proc_stop_deadman_timer/proc_sbe_utils.C | 237 ++++ .../proc_stop_deadman_timer/proc_sbe_utils.H | 96 ++ .../proc_stop_deadman_timer.C | 313 +++-- .../proc_stop_deadman_timer.H | 19 +- .../proc_stop_deadman_timer_errors.xml | 33 +- src/usr/hwpf/hwp/include/p8_istep_num.H | 29 +- src/usr/hwpf/hwp/slave_sbe/slave_sbe.C | 7 + src/usr/hwpf/hwp/system_attributes.xml | 131 ++- src/usr/i2c/runtime/rt_i2c.C | 77 +- .../targeting/common/xmltohb/attribute_types.xml | 112 ++ .../common/xmltohb/attribute_types_hb.xml | 17 + src/usr/targeting/common/xmltohb/target_types.xml | 6 + .../targeting/common/xmltohb/target_types_hb.xml | 1 + 20 files changed, 2141 insertions(+), 334 deletions(-) create mode 100644 src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_intr_service.H create mode 100644 src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.C create mode 100644 src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.H diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C index ff5fce0f3..011ef48e9 100644 --- a/src/usr/devtree/bld_devtree.C +++ b/src/usr/devtree/bld_devtree.C @@ -572,11 +572,14 @@ void bld_fdt_pnor(devTree * i_dt, } void bld_xscom_node(devTree * i_dt, dtOffset_t & i_parentNode, - const TARGETING::Target * i_pProc, uint32_t i_chipid) + const TARGETING::Target * i_pProc, + uint32_t i_chipid, + bool i_smallTree) { const char* xscomNodeName = "xscom"; const char* todNodeName = "chiptod"; const char* pciNodeName = "pbcq"; + const char* sbeTmrNodeName = "sbe-timer"; // Grab a system object to work with TARGETING::Target* sys = NULL; @@ -605,6 +608,30 @@ void bld_xscom_node(devTree * i_dt, dtOffset_t & i_parentNode, uint64_t xscom_prop[2] = { l_xscomAddr, THIRTYTWO_GB}; i_dt->addPropertyCells64(xscomNode, "reg", xscom_prop, 2); + // Add SBE interrupt timer (if enabled) for the master processor + TARGETING::Target* l_pMasterProc = NULL; + TARGETING::targetService().masterProcChipTargetHandle(l_pMasterProc); + if ( (sys->getAttr()) && + (i_pProc == l_pMasterProc) ) + { + dtOffset_t sbeTmrNode = i_dt->addNode(xscomNode, sbeTmrNodeName, + 0xE000A); + uint32_t sbeTmr_prop[6] = {0xE000A, 1, + 0xE0006, 1, + 0x5003A, 1}; + i_dt->addPropertyCells32(sbeTmrNode, "reg", sbeTmr_prop, 6); + const char* sbeTmr_compatStrs[] = {"ibm,power8-sbe-timer",NULL}; + i_dt->addPropertyStrings(sbeTmrNode, "compatible", sbeTmr_compatStrs); + ATTR_SBE_MASTER_INTR_SERVICE_DELAY_US_type l_us = + sys->getAttr(); + i_dt->addPropertyCell32(sbeTmrNode, "tick-time-us", l_us); + } + // Only add SBE interrupt timer for small tree + if (i_smallTree) + { + return; + } + // Add proc chip ECIDs ATTR_ECID_type ecid; i_pProc->tryGetAttr(ecid); @@ -1345,18 +1372,19 @@ errlHndl_t bld_fdt_cpu(devTree * i_dt, std::vector& o_homerRegions, bool i_smallTree) { - // Nothing to do for small trees currently. - if (i_smallTree) { return NULL; } - errlHndl_t errhdl = NULL; /* Find the / node and add a cpus node under it. */ dtOffset_t rootNode = i_dt->findNode("/"); - dtOffset_t cpusNode = i_dt->addNode(rootNode, "cpus"); + dtOffset_t cpusNode = NULL; + if (!i_smallTree) + { + cpusNode = i_dt->addNode(rootNode, "cpus"); - /* Add the # address & size cell properties to /cpus. */ - i_dt->addPropertyCell32(cpusNode, "#address-cells", 1); - i_dt->addPropertyCell32(cpusNode, "#size-cells", 0); + /* Add the # address & size cell properties to /cpus. */ + i_dt->addPropertyCell32(cpusNode, "#address-cells", 1); + i_dt->addPropertyCell32(cpusNode, "#size-cells", 0); + } // Get all functional proc chip targets TARGETING::TargetHandleList l_procTargetList; @@ -1368,7 +1396,17 @@ errlHndl_t bld_fdt_cpu(devTree * i_dt, uint32_t l_chipid = getProcChipId(l_pProc); - bld_xscom_node(i_dt, rootNode, l_pProc, l_chipid); + // For small tree, only add xscom if master processor + TARGETING::Target* l_pMasterProc = NULL; + TARGETING::targetService().masterProcChipTargetHandle(l_pMasterProc); + if((!i_smallTree) || (l_pProc == l_pMasterProc) ) + { + bld_xscom_node(i_dt, rootNode, l_pProc, l_chipid, i_smallTree); + } + if (i_smallTree) // nothing else for small tree + { + continue; + } //Each processor will have a HOMER image that needs //to be reserved -- save it away diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h index 83d11d6dd..0cc4a42ea 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_delta_scan_rw.h,v 1.53 2014/09/11 19:01:13 szhong Exp $ +// $Id: p8_delta_scan_rw.h,v 1.55 2015/05/28 20:28:31 jmcgill Exp $ #define OVERRIDE_OFFSET 8 // Byte offset of forward pointer's addr relative // to base forward pointer's addr. #define SIZE_IMAGE_BUF_MAX 5000000 // Max ~5MB image buffer size. @@ -39,11 +39,24 @@ #define PROC_PIB_REPR_VECTOR_TOC_NAME "proc_sbe_pibmem_repair_vector" #define NEST_SKEWADJUST_VECTOR_TOC_NAME "proc_sbe_nest_skewadjust_vector" #define SECURITY_SETUP_VECTOR_TOC_NAME "proc_sbe_security_setup_vector" +#define PB_BNDY_DMIPLL_REFCLK_SEL_TOC_NAME "pb_bndy_dmipll_refclk_sel_mod" +#define PB_BNDY_DMIPLL_PFD360_TOC_NAME "pb_bndy_dmipll_pfd360_mod" +#define AB_BNDY_PLL_REFCLK_SEL_TOC_NAME "ab_bndy_pll_refclk_sel_mod" +#define AB_BNDY_PLL_PFD360_TOC_NAME "ab_bndy_pll_pfd360_mod" #define VALID_BOOT_CORES_MASK_TOC_NAME "valid_boot_cores_mask" -#define MAX_PLL_RING_SIZE 128 // Bytes +#define PERV_BNDY_PLL_RING_SIZE 128 // Bytes #define PERV_BNDY_PLL_RING_TOC_NAME "perv_bndy_pll_ring" #define PERV_BNDY_PLL_RING_ALT_TOC_NAME "perv_bndy_pll_ring_alt" -#define MAX_FUNC_L3_RING_LIST_ENTRIES 64 +#define PB_BNDY_DMIPLL_RING_SIZE 240 // Bytes +#define PB_BNDY_DMIPLL_RING_TOC_NAME "pb_bndy_dmipll_ring" +#define PB_BNDY_DMIPLL_RING_ALT_TOC_NAME "pb_bndy_dmipll_ring_alt" +#define AB_BNDY_PLL_RING_SIZE 110 // Bytes +#define AB_BNDY_PLL_RING_TOC_NAME "ab_bndy_pll_ring" +#define AB_BNDY_PLL_RING_ALT_TOC_NAME "ab_bndy_pll_ring_alt" +#define PCI_BNDY_PLL_RING_SIZE 110 // Bytes +#define PCI_BNDY_PLL_RING_TOC_NAME "pci_bndy_pll_ring" +#define PCI_BNDY_PLL_RING_ALT_TOC_NAME "pci_bndy_pll_ring_alt" +#define MAX_FUNC_L3_RING_LIST_ENTRIES 64 #define MAX_FUNC_L3_RING_SIZE 7000 // Bytes #define MAX_FARY_L2_RING_LIST_ENTRIES 2 #define MAX_FARY_L2_RING_SIZE 10500 // Bytes @@ -59,6 +72,9 @@ #define UNTRUSTED_PBA_BAR_TOC_NAME "fabric_config_pba" #define REFCLOCK_TERM_TOC_NAME "refclock_term" #define PM_SLEEP_ENABLE_TOC_NAME "pm_sleep_enable" +#define INTR_DECREMENTER_DELAY_CYCLES_NAME "intr_decrementer_delay_cycles" +#define INTR_DECREMENTER_DELAY_US_NAME "intr_decrementer_delay_us" + /***** Scan setting *****/ #define OPCG_SCAN_RATIO 4 diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C index eabae6667..156ecc593 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_xip_customize.C,v 1.74 2014/09/11 19:10:16 szhong Exp $ +// $Id: p8_xip_customize.C,v 1.77 2015/07/27 00:31:05 jmcgill Exp $ /*------------------------------------------------------------------------------*/ /* *! TITLE : p8_xip_customize */ /* *! DESCRIPTION : Obtains repair rings from VPD and adds them to either */ @@ -676,6 +676,163 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostSecuritySetupVec)); } + + // ========================================================================== + // CUSTOMIZE item: DMI PLL ring modification offsets. + // Retrieval method: Attribute. + // System phase: IPL sysPhase. + // Note: TBD + // ========================================================================== + + if (i_sysPhase==0) { + // refclk sel + fapi::ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET_Type refclksel_offset = {0}; + void *hostDMIRefclockSelVec; + uint64_t *hostDMIRefclockSelVec_field; + rc = FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET, &i_target, refclksel_offset); + if (rc) + { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_REFCLKSEL_OFFSET) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( o_imageOut, PB_BNDY_DMIPLL_REFCLK_SEL_TOC_NAME, &xipTocItem); + if (rcLoc) + { + FAPI_INF("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_INF("Probable cause:"); + FAPI_INF("\tThe keyword (=%s) was not found.", PB_BNDY_DMIPLL_REFCLK_SEL_TOC_NAME); + rcLoc = 0; + } + else + { + sbe_xip_pore2host( o_imageOut, xipTocItem.iv_address, &hostDMIRefclockSelVec); + FAPI_INF("Dumping [initial] global variable content of %s, and then the updated value:\n", + PB_BNDY_DMIPLL_REFCLK_SEL_TOC_NAME); + + FAPI_INF(" Before=0x%016llX\n",myRev64(*(uint64_t*)hostDMIRefclockSelVec)); + hostDMIRefclockSelVec_field = (uint64_t*)hostDMIRefclockSelVec; + + for (size_t i = 0; i < 8; i++) + { + *(hostDMIRefclockSelVec_field + i) = myRev64(refclksel_offset[i]); + } + FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostDMIRefclockSelVec)); + } + + + // pfd360 + fapi::ATTR_PROC_DMI_CUPLL_PFD360_OFFSET_Type pfd360_offset = {0}; + void *hostDMIPFD360Vec; + uint64_t *hostDMIPFD360Vec_field; + rc = FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_PFD360_OFFSET, &i_target, pfd360_offset); + if (rc) + { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_DMI_CUPLL_PFD360_OFFSET) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( o_imageOut, PB_BNDY_DMIPLL_PFD360_TOC_NAME, &xipTocItem); + if (rcLoc) + { + FAPI_INF("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_INF("Probable cause:"); + FAPI_INF("\tThe keyword (=%s) was not found.", PB_BNDY_DMIPLL_PFD360_TOC_NAME); + rcLoc = 0; + } + else + { + sbe_xip_pore2host( o_imageOut, xipTocItem.iv_address, &hostDMIPFD360Vec); + FAPI_INF("Dumping [initial] global variable content of %s, and then the updated value:\n", + PB_BNDY_DMIPLL_PFD360_TOC_NAME); + + FAPI_INF(" Before=0x%016llX\n",myRev64(*(uint64_t*)hostDMIPFD360Vec)); + hostDMIPFD360Vec_field = (uint64_t*)hostDMIPFD360Vec; + + for (size_t i = 0; i < 8; i++) + { + *(hostDMIPFD360Vec_field + i) = myRev64(pfd360_offset[i]); + } + FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostDMIPFD360Vec)); + } + } + + + // ========================================================================== + // CUSTOMIZE item: ABUS PLL ring modification offsets. + // Retrieval method: Attribute. + // System phase: IPL sysPhase. + // Note: TBD + // ========================================================================== + + if (i_sysPhase==0) { + // refclk sel + fapi::ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET_Type refclksel_offset = {0}; + void *hostAbusRefclockSelVec; + uint64_t *hostAbusRefclockSelVec_field; + rc = FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET, &i_target, refclksel_offset); + if (rc) + { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_REFCLKSEL_OFFSET) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( o_imageOut, AB_BNDY_PLL_REFCLK_SEL_TOC_NAME, &xipTocItem); + if (rcLoc) + { + FAPI_INF("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_INF("Probable cause:"); + FAPI_INF("\tThe keyword (=%s) was not found.", AB_BNDY_PLL_REFCLK_SEL_TOC_NAME); + rcLoc = 0; + } + else + { + sbe_xip_pore2host( o_imageOut, xipTocItem.iv_address, &hostAbusRefclockSelVec); + FAPI_INF("Dumping [initial] global variable content of %s, and then the updated value:\n", + AB_BNDY_PLL_REFCLK_SEL_TOC_NAME); + + FAPI_INF(" Before=0x%016llX\n",myRev64(*(uint64_t*)hostAbusRefclockSelVec)); + hostAbusRefclockSelVec_field = (uint64_t*)hostAbusRefclockSelVec; + + for (size_t i = 0; i < 3; i++) + { + *(hostAbusRefclockSelVec_field + i) = myRev64(refclksel_offset[i]); + } + FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostAbusRefclockSelVec)); + } + + // pfd360 + fapi::ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET_Type pfd360_offset = {0}; + void *hostAbusPFD360Vec; + uint64_t *hostAbusPFD360Vec_field; + rc = FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET, &i_target, pfd360_offset); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_ABUS_CUPLL_PFD360_OFFSET) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( o_imageOut, AB_BNDY_PLL_PFD360_TOC_NAME, &xipTocItem); + if (rcLoc) + { + FAPI_INF("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_INF("Probable cause:"); + FAPI_INF("\tThe keyword (=%s) was not found.", AB_BNDY_PLL_PFD360_TOC_NAME); + rcLoc = 0; + } + else + { + sbe_xip_pore2host( o_imageOut, xipTocItem.iv_address, &hostAbusPFD360Vec); + FAPI_INF("Dumping [initial] global variable content of %s, and then the updated value:\n", + AB_BNDY_PLL_PFD360_TOC_NAME); + + FAPI_INF(" Before=0x%016llX\n",myRev64(*(uint64_t*)hostAbusPFD360Vec)); + hostAbusPFD360Vec_field = (uint64_t*)hostAbusPFD360Vec; + + for (size_t i = 0; i < 3; i++) + { + *(hostAbusPFD360Vec_field + i) = myRev64(pfd360_offset[i]); + } + FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostAbusPFD360Vec)); + } + } + + // ========================================================================== // CUSTOMIZE item: Untrusted bar settings // Retrieval method: Attribute. @@ -988,8 +1145,8 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, if (i_sysPhase==0) { uint32_t tmp32Const1, tmp32Const2; - uint8_t attrRingFlush[MAX_PLL_RING_SIZE]={0}; - uint8_t attrRingData[MAX_PLL_RING_SIZE]={0}; + uint8_t attrRingFlush[PERV_BNDY_PLL_RING_SIZE]={0}; + uint8_t attrRingData[PERV_BNDY_PLL_RING_SIZE]={0}; uint8_t attrChipletId=0; uint32_t attrScanSelect=0; uint32_t attrRingDataSize=0; // Ring bit size @@ -1004,7 +1161,7 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, // // Retrieve the raw PLL rings state from attributes. // - FAPI_INF("XIPC: PLL update: Retrieve the raw PLL ring state from attributes."); + FAPI_INF("XIPC: PERV_BNDY_PLL update: Retrieve the raw PLL ring state from attributes."); // Get ring size. rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_LENGTH, &i_target, attrRingDataSize); // This better be in bits. FAPI_INF("XIPC: PLL update: PLL ring length (bits) = %i",attrRingDataSize); @@ -1013,14 +1170,14 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_LENGTH) returned error."); return rc; } - if (attrRingDataSize>MAX_PLL_RING_SIZE*8 || attrRingDataSize>i_sizeBuf1*8) { + if (attrRingDataSize>PERV_BNDY_PLL_RING_SIZE*8 || attrRingDataSize>i_sizeBuf1*8) { FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_LENGTH) returned ring size =%i bits.\n", attrRingDataSize); FAPI_ERR("But that exceeds either:\n"); - FAPI_ERR(" the max pll ring size =%i bits, or\n",MAX_PLL_RING_SIZE*8); + FAPI_ERR(" the max pll ring size =%i bits, or\n",PERV_BNDY_PLL_RING_SIZE*8); FAPI_ERR(" the size of the pre-allocated buf1 =%i bits.", i_sizeBuf1*8); uint32_t &DATA_ATTRIBUTE_RING_SIZE=attrRingDataSize; - tmp32Const1=8*MAX_PLL_RING_SIZE; + tmp32Const1=8*PERV_BNDY_PLL_RING_SIZE; tmp32Const2=8*(uint32_t)i_sizeBuf1; uint32_t &DATA_MAX_PLL_RING_SIZE=tmp32Const1; uint32_t &DATA_SIZE_OF_BUF1=tmp32Const2; @@ -1049,7 +1206,7 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_SCAN_SELECT) returned error."); return rc; } - + // // Calculate the delta scan ring. // @@ -1066,7 +1223,7 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); return rc; } - + // // RS4 compress the delta scan ring. // @@ -1103,7 +1260,7 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, FAPI_INF("Compression Successful."); // - // Build the PLL _alt ring block (= ring header + RS4 launcher + RS4 ring). + // Build the PLL _alt ring block (= ring header + RS4 launcher + RS4 ring). // uint64_t scanChipletAddress=0; uint32_t asmBuffer[ASM_RS4_LAUNCH_BUF_SIZE/4]; @@ -1113,7 +1270,7 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, // Reuse i_buf1 to hold the ring block. bufPllRingAltBlock = (DeltaRingLayout*)i_buf1; sizePllRingAltBlockMax = i_sizeBuf1; - + // Construct RS4 launcher: // ...get the RS4 decompress address. rcLoc = sbe_xip_get_scalar( o_imageOut, "proc_sbe_decompress_scan_chiplet_address", &scanChipletAddress); @@ -1151,8 +1308,8 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, return rc; } sizeRs4Launch = ctx.lc; - - // Populate ring header and put ring header, RS4 launcher and RS4 ring into + + // Populate ring header and put ring header, RS4 launcher and RS4 ring into // proper spots in pre-allocated bufPllRingAltBlock buffer. // uint64_t entryOffsetPllRingAltBlock; @@ -1184,12 +1341,12 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, // Copy over RS4 launch code which is [already] BE and 8-byte aligned. memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, asmBuffer, (size_t)sizeRs4Launch); // Copy over RS4 PLL _alt delta scan ring which is [already] 8-byte aligned. - bufLC = bufLC + sizeRs4Launch; + bufLC = bufLC + sizeRs4Launch; memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, bufPllRingAltRs4, (size_t)sizePllRingAltRs4); // Now, some post-sanity checks on alignments. if ( sizeRs4Launch!=ASM_RS4_LAUNCH_BUF_SIZE || - entryOffsetPllRingAltBlock%8 || + entryOffsetPllRingAltBlock%8 || sizeRs4Launch%8 || sizeOfThisPllRingAltBlock%8) { FAPI_ERR("Member(s) of PLL _alt ring block are not 8-byte aligned:"); @@ -1204,7 +1361,7 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, return rc; } - + // // Append PLL _alt ring to image. // @@ -1228,104 +1385,882 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, } } -#endif - -#ifndef IMGBUILD_PPD_IGNORE_VPD // ========================================================================== - // CUSTOMIZE item: Add #G and #R rings. - // Retrieval method: MVPD - // System phase: Applies to both sysPhase modes: IPL and SLW. - // Notes: For SLW, only update ex_ chiplet rings. + // CUSTOMIZE item: Update PLL ring (ab_bndy_pll_ring_alt). + // Retrieval method: Attribute. + // System phase: IPL sysPhase. // ========================================================================== - SbeXipSection xipSectionDcrings; - - // First, is there an .dcrings section yet in the input image? We need this to know - // if we should do datacare on #G rings a little later. - // (Note, it makes no sense checking in output image since SLW has been wiped clean, and - // the same may be the case with IPL image in the future.) - rcLoc = sbe_xip_get_section(i_imageIn, SBE_XIP_SECTION_DCRINGS, &xipSectionDcrings); - if (rcLoc) { - FAPI_ERR("_get_section(.dcrings...) failed with rc=%i ",rcLoc); - uint32_t &RC_LOCAL=rcLoc; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); - return rc; - } - - if (i_sysPhase==0 && !largeSeeprom) { - // The .dcrings section will eventually be removed from the image, so set the - // max size to final output size max + .dcrings size if we can - sizeImageMax = min(MAX_SEEPROM_IMAGE_SIZE + xipSectionDcrings.iv_size, sizeImageOutMax); - } else { - sizeImageMax = sizeImageOutMax; - } - // First, insert the chiplet XX rings - rc = p8_xip_customize_insert_chiplet_rings( i_target, - i_imageIn, - o_imageOut, - i_sysPhase, - i_buf1, - i_sizeBuf1, - i_buf2, - i_sizeBuf2, - attrDdLevel, + if (i_sysPhase==0) { + uint32_t tmp32Const1, tmp32Const2; + uint8_t attrRingFlush[AB_BNDY_PLL_RING_SIZE]={0}; + uint8_t attrRingData[AB_BNDY_PLL_RING_SIZE]={0}; + uint8_t attrChipletId=0; + uint32_t attrScanSelect=0; + uint32_t attrRingDataSize=0; // Ring bit size + uint32_t sizeDeltaPllRingAlt=0; + uint32_t sizeRs4Launch=0; + uint8_t *bufDeltaPllRingAlt; + CompressedScanData *bufPllRingAltRs4; + uint32_t sizePllRingAltRs4Max, sizePllRingAltRs4, sizePllRingAltBlockMax; + DeltaRingLayout *bufPllRingAltBlock; + uint32_t bufLC=0; - sizeImageMax, - 0xFF, - xipSectionDcrings - ); - if (rc) return rc; + // + // Retrieve the raw PLL rings state from attributes. + // + FAPI_INF("XIPC: AB_BNDY_PLL update: Retrieve the raw PLL ring state from attributes."); + // Get ring size. + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH, &i_target, attrRingDataSize); // This better be in bits. + FAPI_INF("XIPC: PLL update: PLL ring length (bits) = %i",attrRingDataSize); + FAPI_INF("XIPC: PLL update: Size of buf1, i_sizeBuf1 (bytes) = %i",i_sizeBuf1); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH) returned error."); + return rc; + } + if (attrRingDataSize>AB_BNDY_PLL_RING_SIZE*8 || attrRingDataSize>i_sizeBuf1*8) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_LENGTH) returned ring size =%i bits.\n", + attrRingDataSize); + FAPI_ERR("But that exceeds either:\n"); + FAPI_ERR(" the max pll ring size =%i bits, or\n",AB_BNDY_PLL_RING_SIZE*8); + FAPI_ERR(" the size of the pre-allocated buf1 =%i bits.", i_sizeBuf1*8); + uint32_t &DATA_ATTRIBUTE_RING_SIZE=attrRingDataSize; + tmp32Const1=8*AB_BNDY_PLL_RING_SIZE; + tmp32Const2=8*(uint32_t)i_sizeBuf1; + uint32_t &DATA_MAX_PLL_RING_SIZE=tmp32Const1; + uint32_t &DATA_SIZE_OF_BUF1=tmp32Const2; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PLL_RING_SIZE_TOO_LARGE); + return rc; + } + sizeDeltaPllRingAlt = attrRingDataSize; // We already checked it'll fit into buf1. + // Get flush and alter (desired) ring state data. + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_FLUSH, &i_target, attrRingFlush); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_FLUSH) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA, &i_target, attrRingData); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_DATA) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_CHIPLET_ID, &i_target, attrChipletId); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_CHIPLET_ID) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_SCAN_SELECT, &i_target, attrScanSelect); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_AB_BNDY_PLL_SCAN_SELECT) returned error."); + return rc; + } - // Then loop through the chiplets - uint32_t validEXCount = 0; - uint8_t chipletId; - io_bootCoreMask = 0; - for (chipletId = CHIPLET_ID_MIN; chipletId <= CHIPLET_ID_MAX; chipletId++) { - // Only process functional chiplets - // Note - currently the SBE treats bad cores (0x93) as non-functional (0x00) - // so inserting rings for those wastes space. I'll assume that they - // won't be in the desiredBootCoreMask and thus won't get rings, - // rather than checking for that case because the SBE code may change. - if (attrCombGoodVec[chipletId]) { - // Special handling for EX chiplet IDs - if ((chipletId >= CHIPLET_ID_EX_MIN) && (chipletId <= CHIPLET_ID_EX_MAX)) { - if (desiredBootCoreMask & (0x80000000 >> chipletId)) { - rc = p8_xip_customize_insert_chiplet_rings( i_target, - i_imageIn, - o_imageOut, - i_sysPhase, - i_buf1, - i_sizeBuf1, - i_buf2, - i_sizeBuf2, - attrDdLevel, - sizeImageMax, - chipletId, - xipSectionDcrings - ); - if (rc) { - // Check if this is just a case of trying to fit in too many EXs - if ((i_sysPhase == 0) && - (rc == RC_PROC_XIPC_RING_WRITE_WOULD_OVERFLOW)) - { + // + // Calculate the delta scan ring. + // + FAPI_INF("XIPC: PLL update: Calculate the delta scan ring."); + bufDeltaPllRingAlt = (uint8_t*)i_buf1; + rcLoc = calc_ring_delta_state( (uint32_t*)attrRingFlush, + (uint32_t*)attrRingData, + (uint32_t*)bufDeltaPllRingAlt, // Pre-allocated buffer. + sizeDeltaPllRingAlt ); + if (rcLoc) { + FAPI_ERR("calc_ring_delta_state() returned error w/rc=%i",rcLoc); + FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } - uint32_t MINIMUM_VALID_EXS; - fapi::ReturnCode lrc; - lrc = FAPI_ATTR_GET(ATTR_SBE_IMAGE_MINIMUM_VALID_EXS, NULL, MINIMUM_VALID_EXS); - if (lrc) - { - FAPI_INF("Unable to determine ATTR_SBE_IMAGE_MINIMUM_VALID_EXS, so don't know if the minimum was met"); - fapiLogError(lrc); - uint32_t & VALID_COUNT = validEXCount; - uint32_t & MINIMUM = MINIMUM_VALID_EXS; - const uint32_t & DESIRED_CORES = desiredBootCoreMask; - uint32_t & BOOT_CORE_MASK = io_bootCoreMask; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RING_WRITE_WOULD_OVERFLOW_ADD_INFO); - return rc; - } + // + // RS4 compress the delta scan ring. + // + FAPI_INF("XIPC: PLL update: RS4 compressing the delta scan ring."); + bufPllRingAltRs4 = (CompressedScanData*)i_buf2; + sizePllRingAltRs4Max = i_sizeBuf2; // Always supply max buffer space for ring. + rcLoc = _rs4_compress(bufPllRingAltRs4, // Contains PLL _alt RS4 ring on return. + sizePllRingAltRs4Max, // Max size of buffer. + &sizePllRingAltRs4, // Returned final size of RS4 ring + container. + bufDeltaPllRingAlt, // Input delta scan ring. + sizeDeltaPllRingAlt, // Input delta scan ring size. + (uint64_t)attrScanSelect<<32, + 0, + attrChipletId, + 1 ); // Always flush optimize for base rings. + if (rcLoc) { + FAPI_ERR("_rs4_compress() failed w/rc=%i",rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RS4_COMPRESS_ERROR); + return rc; + } + else + if (sizePllRingAltRs4!=myRev32(bufPllRingAltRs4->iv_size)) { + FAPI_ERR("_rs4_compress() problem with size of RS4 ring (incl container)."); + FAPI_ERR("Returned size = %i", sizePllRingAltRs4); + FAPI_ERR("Size from container = %i", myRev32(bufPllRingAltRs4->iv_size)); + uint32_t &DATA_SIZE_RS4_COMPRESS_RETURN=sizePllRingAltRs4; + tmp32Const1=myRev32(bufPllRingAltRs4->iv_size); + uint32_t &DATA_SIZE_RS4_COMPRESS_CONTAINER=tmp32Const1; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RS4_COMPRESS_SIZE_MESS); + return rc; + } + else + FAPI_INF("Compression Successful."); - if (validEXCount < MINIMUM_VALID_EXS) + // + // Build the PLL _alt ring block (= ring header + RS4 launcher + RS4 ring). + // + uint64_t scanChipletAddress=0; + uint32_t asmBuffer[ASM_RS4_LAUNCH_BUF_SIZE/4]; + PoreInlineContext ctx; + + FAPI_INF("XIPC: PLL update: Building the RS4 PLL ring block."); + // Reuse i_buf1 to hold the ring block. + bufPllRingAltBlock = (DeltaRingLayout*)i_buf1; + sizePllRingAltBlockMax = i_sizeBuf1; + + // Construct RS4 launcher: + // ...get the RS4 decompress address. + rcLoc = sbe_xip_get_scalar( o_imageOut, "proc_sbe_decompress_scan_chiplet_address", &scanChipletAddress); + if (rcLoc) { + FAPI_ERR("sbe_xip_get_scalar() failed w/rc=%i", rcLoc); + FAPI_ERR("Probable cause: Key word =proc_sbe_decompress_scan_chiplet_address not found in image."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (scanChipletAddress==0) { + FAPI_ERR("Value of key word (=proc_sbe_decompress_scan_chiplet_address=0) not permitted."); + uint64_t &DATA_RS4_DECOMPRESS_ADDR=scanChipletAddress; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_ILLEGAL_RS4_DECOMPRESS_ADDR); + return rc; + } + // ... create inline asm code. + pore_inline_context_create( &ctx, asmBuffer, ASM_RS4_LAUNCH_BUF_SIZE*4, 0, 0); + rcLoc = ctx.error; + if (rcLoc) { + FAPI_ERR("pore_inline_context_create() failed w/rc=%i", rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PORE_INLINE_CTX_CREATE_ERROR); + return rc; + } + pore_MR(&ctx, A0, PC); + pore_ADDS(&ctx, A0, A0, ASM_RS4_LAUNCH_BUF_SIZE); + pore_LI(&ctx, D0, scanChipletAddress); + pore_BRAD(&ctx, D0); + rcLoc = ctx.error; + if (rcLoc) { + FAPI_ERR("pore_MR/ADDS/LI/BRAD() failed w/rc=%i", rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PORE_INLINE_RS4_LAUNCH_CREATE_ERROR); + return rc; + } + sizeRs4Launch = ctx.lc; + + // Populate ring header and put ring header, RS4 launcher and RS4 ring into + // proper spots in pre-allocated bufPllRingAltBlock buffer. + // + uint64_t entryOffsetPllRingAltBlock; + uint32_t sizeOfThisPllRingAltBlock; + entryOffsetPllRingAltBlock = calc_ring_layout_entry_offset( 0, 0); + bufPllRingAltBlock->entryOffset = myRev64(entryOffsetPllRingAltBlock); + bufPllRingAltBlock->backItemPtr = 0; // Will be updated below, as we don't know yet. + sizeOfThisPllRingAltBlock = entryOffsetPllRingAltBlock + // Must be 8-byte aligned. + sizeRs4Launch + // Must be 8-byte aligned. + sizePllRingAltRs4; // Must be 8-byte aligned. + bufPllRingAltBlock->sizeOfThis = myRev32(sizeOfThisPllRingAltBlock); + // Quick check to see if final ring block size will fit in buf1. + if (sizeOfThisPllRingAltBlock>sizePllRingAltBlockMax) { + FAPI_ERR("PLL _alt ring block size (=%i) exceeds pre-allocated buf1 size (=%i).", + sizeOfThisPllRingAltBlock, sizePllRingAltBlockMax); + uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeOfThisPllRingAltBlock; + uint32_t &DATA_SIZE_OF_BUF1=sizePllRingAltBlockMax; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PLL_RING_BLOCK_TOO_LARGE); + return rc; + } + bufPllRingAltBlock->sizeOfMeta = 0; + bufPllRingAltBlock->ddLevel = myRev32((uint32_t)attrDdLevel); + bufPllRingAltBlock->sysPhase = i_sysPhase; + bufPllRingAltBlock->override = 0; + bufPllRingAltBlock->reserved1 = 0; + bufPllRingAltBlock->reserved2 = 0; + bufLC = (uint32_t)entryOffsetPllRingAltBlock; + // Copy over meta data which is zero, so nothing to do in this case! + // Copy over RS4 launch code which is [already] BE and 8-byte aligned. + memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, asmBuffer, (size_t)sizeRs4Launch); + // Copy over RS4 PLL _alt delta scan ring which is [already] 8-byte aligned. + bufLC = bufLC + sizeRs4Launch; + memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, bufPllRingAltRs4, (size_t)sizePllRingAltRs4); + + // Now, some post-sanity checks on alignments. + if ( sizeRs4Launch!=ASM_RS4_LAUNCH_BUF_SIZE || + entryOffsetPllRingAltBlock%8 || + sizeRs4Launch%8 || + sizeOfThisPllRingAltBlock%8) { + FAPI_ERR("Member(s) of PLL _alt ring block are not 8-byte aligned:"); + FAPI_ERR(" Size of RS4 launch code = %i", sizeRs4Launch); + FAPI_ERR(" Entry offset = %i", (uint32_t)entryOffsetPllRingAltBlock); + FAPI_ERR(" Size of ring block = %i", sizeOfThisPllRingAltBlock); + uint32_t &DATA_SIZE_OF_RS4_LAUNCH=sizeRs4Launch; + tmp32Const1=(uint32_t)entryOffsetPllRingAltBlock; + uint32_t &DATA_RING_BLOCK_ENTRYOFFSET=tmp32Const1; + uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeOfThisPllRingAltBlock; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RING_BLOCK_ALIGN_ERROR); + return rc; + } + + // + // Append PLL _alt ring to image. + // + SbeXipItem tocItem; + rcLoc = sbe_xip_find(o_imageOut, AB_BNDY_PLL_RING_ALT_TOC_NAME, &tocItem); + if (rcLoc) + { + FAPI_INF("Skipping PLL update for %s", AB_BNDY_PLL_RING_ALT_TOC_NAME); + rcLoc = 0; + } + else + { + FAPI_INF("XIPC: PLL update: Appending RS4 PLL ring block to .rings section."); + rcLoc = write_ring_block_to_image( o_imageOut, + AB_BNDY_PLL_RING_ALT_TOC_NAME, + bufPllRingAltBlock, + 0, + 0, + 0, + largeSeeprom? sizeImageOutMax:MAX_SEEPROM_IMAGE_SIZE, // OK, since sysPhase=0. + SBE_XIP_SECTION_RINGS, + i_buf2, + i_sizeBuf2); + if (rcLoc) + { + FAPI_ERR("write_ring_block_to_image() failed for %s w/rc=%i", AB_BNDY_PLL_RING_ALT_TOC_NAME, rcLoc); + FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } + } + } + + // ========================================================================== + // CUSTOMIZE item: Update PLL ring (pci_bndy_pll_ring_alt). + // Retrieval method: Attribute. + // System phase: IPL sysPhase. + // ========================================================================== + + if (i_sysPhase==0) { + uint32_t tmp32Const1, tmp32Const2; + uint8_t attrRingFlush[PCI_BNDY_PLL_RING_SIZE]={0}; + uint8_t attrRingData[PCI_BNDY_PLL_RING_SIZE]={0}; + uint8_t attrChipletId=0; + uint32_t attrScanSelect=0; + uint32_t attrRingDataSize=0; // Ring bit size + uint32_t sizeDeltaPllRingAlt=0; + uint32_t sizeRs4Launch=0; + uint8_t *bufDeltaPllRingAlt; + CompressedScanData *bufPllRingAltRs4; + uint32_t sizePllRingAltRs4Max, sizePllRingAltRs4, sizePllRingAltBlockMax; + DeltaRingLayout *bufPllRingAltBlock; + uint32_t bufLC=0; + + // + // Retrieve the raw PLL rings state from attributes. + // + FAPI_INF("XIPC: PCI_BNDY_PLL update: Retrieve the raw PLL ring state from attributes."); + // Get ring size. + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_LENGTH, &i_target, attrRingDataSize); // This better be in bits. + FAPI_INF("XIPC: PLL update: PLL ring length (bits) = %i",attrRingDataSize); + FAPI_INF("XIPC: PLL update: Size of buf1, i_sizeBuf1 (bytes) = %i",i_sizeBuf1); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_LENGTH) returned error."); + return rc; + } + if (attrRingDataSize>PCI_BNDY_PLL_RING_SIZE*8 || attrRingDataSize>i_sizeBuf1*8) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_LENGTH) returned ring size =%i bits.\n", + attrRingDataSize); + FAPI_ERR("But that exceeds either:\n"); + FAPI_ERR(" the max pll ring size =%i bits, or\n",PCI_BNDY_PLL_RING_SIZE*8); + FAPI_ERR(" the size of the pre-allocated buf1 =%i bits.", i_sizeBuf1*8); + uint32_t &DATA_ATTRIBUTE_RING_SIZE=attrRingDataSize; + tmp32Const1=8*PCI_BNDY_PLL_RING_SIZE; + tmp32Const2=8*(uint32_t)i_sizeBuf1; + uint32_t &DATA_MAX_PLL_RING_SIZE=tmp32Const1; + uint32_t &DATA_SIZE_OF_BUF1=tmp32Const2; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PLL_RING_SIZE_TOO_LARGE); + return rc; + } + sizeDeltaPllRingAlt = attrRingDataSize; // We already checked it'll fit into buf1. + // Get flush and alter (desired) ring state data. + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_FLUSH, &i_target, attrRingFlush); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_FLUSH) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_DATA, &i_target, attrRingData); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_DATA) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_CHIPLET_ID, &i_target, attrChipletId); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_CHIPLET_ID) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_SCAN_SELECT, &i_target, attrScanSelect); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PCI_BNDY_PLL_SCAN_SELECT) returned error."); + return rc; + } + + // + // Calculate the delta scan ring. + // + FAPI_INF("XIPC: PLL update: Calculate the delta scan ring."); + bufDeltaPllRingAlt = (uint8_t*)i_buf1; + rcLoc = calc_ring_delta_state( (uint32_t*)attrRingFlush, + (uint32_t*)attrRingData, + (uint32_t*)bufDeltaPllRingAlt, // Pre-allocated buffer. + sizeDeltaPllRingAlt ); + if (rcLoc) { + FAPI_ERR("calc_ring_delta_state() returned error w/rc=%i",rcLoc); + FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } + + // + // RS4 compress the delta scan ring. + // + FAPI_INF("XIPC: PLL update: RS4 compressing the delta scan ring."); + bufPllRingAltRs4 = (CompressedScanData*)i_buf2; + sizePllRingAltRs4Max = i_sizeBuf2; // Always supply max buffer space for ring. + rcLoc = _rs4_compress(bufPllRingAltRs4, // Contains PLL _alt RS4 ring on return. + sizePllRingAltRs4Max, // Max size of buffer. + &sizePllRingAltRs4, // Returned final size of RS4 ring + container. + bufDeltaPllRingAlt, // Input delta scan ring. + sizeDeltaPllRingAlt, // Input delta scan ring size. + (uint64_t)attrScanSelect<<32, + 0, + attrChipletId, + 1 ); // Always flush optimize for base rings. + if (rcLoc) { + FAPI_ERR("_rs4_compress() failed w/rc=%i",rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RS4_COMPRESS_ERROR); + return rc; + } + else + if (sizePllRingAltRs4!=myRev32(bufPllRingAltRs4->iv_size)) { + FAPI_ERR("_rs4_compress() problem with size of RS4 ring (incl container)."); + FAPI_ERR("Returned size = %i", sizePllRingAltRs4); + FAPI_ERR("Size from container = %i", myRev32(bufPllRingAltRs4->iv_size)); + uint32_t &DATA_SIZE_RS4_COMPRESS_RETURN=sizePllRingAltRs4; + tmp32Const1=myRev32(bufPllRingAltRs4->iv_size); + uint32_t &DATA_SIZE_RS4_COMPRESS_CONTAINER=tmp32Const1; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RS4_COMPRESS_SIZE_MESS); + return rc; + } + else + FAPI_INF("Compression Successful."); + + // + // Build the PLL _alt ring block (= ring header + RS4 launcher + RS4 ring). + // + uint64_t scanChipletAddress=0; + uint32_t asmBuffer[ASM_RS4_LAUNCH_BUF_SIZE/4]; + PoreInlineContext ctx; + + FAPI_INF("XIPC: PLL update: Building the RS4 PLL ring block."); + // Reuse i_buf1 to hold the ring block. + bufPllRingAltBlock = (DeltaRingLayout*)i_buf1; + sizePllRingAltBlockMax = i_sizeBuf1; + + // Construct RS4 launcher: + // ...get the RS4 decompress address. + rcLoc = sbe_xip_get_scalar( o_imageOut, "proc_sbe_decompress_scan_chiplet_address", &scanChipletAddress); + if (rcLoc) { + FAPI_ERR("sbe_xip_get_scalar() failed w/rc=%i", rcLoc); + FAPI_ERR("Probable cause: Key word =proc_sbe_decompress_scan_chiplet_address not found in image."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (scanChipletAddress==0) { + FAPI_ERR("Value of key word (=proc_sbe_decompress_scan_chiplet_address=0) not permitted."); + uint64_t &DATA_RS4_DECOMPRESS_ADDR=scanChipletAddress; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_ILLEGAL_RS4_DECOMPRESS_ADDR); + return rc; + } + // ... create inline asm code. + pore_inline_context_create( &ctx, asmBuffer, ASM_RS4_LAUNCH_BUF_SIZE*4, 0, 0); + rcLoc = ctx.error; + if (rcLoc) { + FAPI_ERR("pore_inline_context_create() failed w/rc=%i", rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PORE_INLINE_CTX_CREATE_ERROR); + return rc; + } + pore_MR(&ctx, A0, PC); + pore_ADDS(&ctx, A0, A0, ASM_RS4_LAUNCH_BUF_SIZE); + pore_LI(&ctx, D0, scanChipletAddress); + pore_BRAD(&ctx, D0); + rcLoc = ctx.error; + if (rcLoc) { + FAPI_ERR("pore_MR/ADDS/LI/BRAD() failed w/rc=%i", rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PORE_INLINE_RS4_LAUNCH_CREATE_ERROR); + return rc; + } + sizeRs4Launch = ctx.lc; + + // Populate ring header and put ring header, RS4 launcher and RS4 ring into + // proper spots in pre-allocated bufPllRingAltBlock buffer. + // + uint64_t entryOffsetPllRingAltBlock; + uint32_t sizeOfThisPllRingAltBlock; + entryOffsetPllRingAltBlock = calc_ring_layout_entry_offset( 0, 0); + bufPllRingAltBlock->entryOffset = myRev64(entryOffsetPllRingAltBlock); + bufPllRingAltBlock->backItemPtr = 0; // Will be updated below, as we don't know yet. + sizeOfThisPllRingAltBlock = entryOffsetPllRingAltBlock + // Must be 8-byte aligned. + sizeRs4Launch + // Must be 8-byte aligned. + sizePllRingAltRs4; // Must be 8-byte aligned. + bufPllRingAltBlock->sizeOfThis = myRev32(sizeOfThisPllRingAltBlock); + // Quick check to see if final ring block size will fit in buf1. + if (sizeOfThisPllRingAltBlock>sizePllRingAltBlockMax) { + FAPI_ERR("PLL _alt ring block size (=%i) exceeds pre-allocated buf1 size (=%i).", + sizeOfThisPllRingAltBlock, sizePllRingAltBlockMax); + uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeOfThisPllRingAltBlock; + uint32_t &DATA_SIZE_OF_BUF1=sizePllRingAltBlockMax; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PLL_RING_BLOCK_TOO_LARGE); + return rc; + } + bufPllRingAltBlock->sizeOfMeta = 0; + bufPllRingAltBlock->ddLevel = myRev32((uint32_t)attrDdLevel); + bufPllRingAltBlock->sysPhase = i_sysPhase; + bufPllRingAltBlock->override = 0; + bufPllRingAltBlock->reserved1 = 0; + bufPllRingAltBlock->reserved2 = 0; + bufLC = (uint32_t)entryOffsetPllRingAltBlock; + // Copy over meta data which is zero, so nothing to do in this case! + // Copy over RS4 launch code which is [already] BE and 8-byte aligned. + memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, asmBuffer, (size_t)sizeRs4Launch); + // Copy over RS4 PLL _alt delta scan ring which is [already] 8-byte aligned. + bufLC = bufLC + sizeRs4Launch; + memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, bufPllRingAltRs4, (size_t)sizePllRingAltRs4); + + // Now, some post-sanity checks on alignments. + if ( sizeRs4Launch!=ASM_RS4_LAUNCH_BUF_SIZE || + entryOffsetPllRingAltBlock%8 || + sizeRs4Launch%8 || + sizeOfThisPllRingAltBlock%8) { + FAPI_ERR("Member(s) of PLL _alt ring block are not 8-byte aligned:"); + FAPI_ERR(" Size of RS4 launch code = %i", sizeRs4Launch); + FAPI_ERR(" Entry offset = %i", (uint32_t)entryOffsetPllRingAltBlock); + FAPI_ERR(" Size of ring block = %i", sizeOfThisPllRingAltBlock); + uint32_t &DATA_SIZE_OF_RS4_LAUNCH=sizeRs4Launch; + tmp32Const1=(uint32_t)entryOffsetPllRingAltBlock; + uint32_t &DATA_RING_BLOCK_ENTRYOFFSET=tmp32Const1; + uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeOfThisPllRingAltBlock; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RING_BLOCK_ALIGN_ERROR); + return rc; + } + + + // + // Append PLL _alt ring to image. + // + SbeXipItem tocItem; + rcLoc = sbe_xip_find(o_imageOut, PCI_BNDY_PLL_RING_ALT_TOC_NAME, &tocItem); + if (rcLoc) + { + FAPI_INF("Skipping PLL update for %s", PCI_BNDY_PLL_RING_ALT_TOC_NAME); + rcLoc = 0; + } + else + { + FAPI_INF("XIPC: PLL update: Appending RS4 PLL ring block to .rings section."); + rcLoc = write_ring_block_to_image( o_imageOut, + PCI_BNDY_PLL_RING_ALT_TOC_NAME, + bufPllRingAltBlock, + 0, + 0, + 0, + largeSeeprom? sizeImageOutMax:MAX_SEEPROM_IMAGE_SIZE, // OK, since sysPhase=0. + SBE_XIP_SECTION_RINGS, + i_buf2, + i_sizeBuf2); + if (rcLoc) + { + FAPI_ERR("write_ring_block_to_image() failed for %s w/rc=%i", PCI_BNDY_PLL_RING_ALT_TOC_NAME, rcLoc); + FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } + } + + } + + // ========================================================================== + // CUSTOMIZE item: Update PLL ring (pb_bndy_dmipll_ring_alt). + // Retrieval method: Attribute. + // System phase: IPL sysPhase. + // ========================================================================== + + if (i_sysPhase==0) { + uint32_t tmp32Const1, tmp32Const2; + uint8_t attrRingFlush[PB_BNDY_DMIPLL_RING_SIZE]={0}; + uint8_t attrRingData[PB_BNDY_DMIPLL_RING_SIZE]={0}; + uint8_t attrChipletId=0; + uint32_t attrScanSelect=0; + uint32_t attrRingDataSize=0; // Ring bit size + uint32_t sizeDeltaPllRingAlt=0; + uint32_t sizeRs4Launch=0; + uint8_t *bufDeltaPllRingAlt; + CompressedScanData *bufPllRingAltRs4; + uint32_t sizePllRingAltRs4Max, sizePllRingAltRs4, sizePllRingAltBlockMax; + DeltaRingLayout *bufPllRingAltBlock; + uint32_t bufLC=0; + + // + // Retrieve the raw PLL rings state from attributes. + // + FAPI_INF("XIPC: PB_BNDY_DMIPLL update: Retrieve the raw PLL ring state from attributes."); + // Get ring size. + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH, &i_target, attrRingDataSize); // This better be in bits. + FAPI_INF("XIPC: PLL update: PLL ring length (bits) = %i",attrRingDataSize); + FAPI_INF("XIPC: PLL update: Size of buf1, i_sizeBuf1 (bytes) = %i",i_sizeBuf1); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH) returned error."); + return rc; + } + if (attrRingDataSize>PB_BNDY_DMIPLL_RING_SIZE*8 || attrRingDataSize>i_sizeBuf1*8) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_LENGTH) returned ring size =%i bits.\n", + attrRingDataSize); + FAPI_ERR("But that exceeds either:\n"); + FAPI_ERR(" the max pll ring size =%i bits, or\n",PB_BNDY_DMIPLL_RING_SIZE*8); + FAPI_ERR(" the size of the pre-allocated buf1 =%i bits.", i_sizeBuf1*8); + uint32_t &DATA_ATTRIBUTE_RING_SIZE=attrRingDataSize; + tmp32Const1=8*PB_BNDY_DMIPLL_RING_SIZE; + tmp32Const2=8*(uint32_t)i_sizeBuf1; + uint32_t &DATA_MAX_PLL_RING_SIZE=tmp32Const1; + uint32_t &DATA_SIZE_OF_BUF1=tmp32Const2; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PLL_RING_SIZE_TOO_LARGE); + return rc; + } + sizeDeltaPllRingAlt = attrRingDataSize; // We already checked it'll fit into buf1. + // Get flush and alter (desired) ring state data. + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_FLUSH, &i_target, attrRingFlush); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_FLUSH) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA, &i_target, attrRingData); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_DATA) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_CHIPLET_ID, &i_target, attrChipletId); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_CHIPLET_ID) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_SCAN_SELECT, &i_target, attrScanSelect); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PB_BNDY_DMIPLL_SCAN_SELECT) returned error."); + return rc; + } + + // + // Calculate the delta scan ring. + // + FAPI_INF("XIPC: PLL update: Calculate the delta scan ring."); + bufDeltaPllRingAlt = (uint8_t*)i_buf1; + rcLoc = calc_ring_delta_state( (uint32_t*)attrRingFlush, + (uint32_t*)attrRingData, + (uint32_t*)bufDeltaPllRingAlt, // Pre-allocated buffer. + sizeDeltaPllRingAlt ); + if (rcLoc) { + FAPI_ERR("calc_ring_delta_state() returned error w/rc=%i",rcLoc); + FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } + + // + // RS4 compress the delta scan ring. + // + FAPI_INF("XIPC: PLL update: RS4 compressing the delta scan ring."); + bufPllRingAltRs4 = (CompressedScanData*)i_buf2; + sizePllRingAltRs4Max = i_sizeBuf2; // Always supply max buffer space for ring. + rcLoc = _rs4_compress(bufPllRingAltRs4, // Contains PLL _alt RS4 ring on return. + sizePllRingAltRs4Max, // Max size of buffer. + &sizePllRingAltRs4, // Returned final size of RS4 ring + container. + bufDeltaPllRingAlt, // Input delta scan ring. + sizeDeltaPllRingAlt, // Input delta scan ring size. + (uint64_t)attrScanSelect<<32, + 0, + attrChipletId, + 1 ); // Always flush optimize for base rings. + if (rcLoc) { + FAPI_ERR("_rs4_compress() failed w/rc=%i",rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RS4_COMPRESS_ERROR); + return rc; + } + else + if (sizePllRingAltRs4!=myRev32(bufPllRingAltRs4->iv_size)) { + FAPI_ERR("_rs4_compress() problem with size of RS4 ring (incl container)."); + FAPI_ERR("Returned size = %i", sizePllRingAltRs4); + FAPI_ERR("Size from container = %i", myRev32(bufPllRingAltRs4->iv_size)); + uint32_t &DATA_SIZE_RS4_COMPRESS_RETURN=sizePllRingAltRs4; + tmp32Const1=myRev32(bufPllRingAltRs4->iv_size); + uint32_t &DATA_SIZE_RS4_COMPRESS_CONTAINER=tmp32Const1; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RS4_COMPRESS_SIZE_MESS); + return rc; + } + else + FAPI_INF("Compression Successful."); + + // + // Build the PLL _alt ring block (= ring header + RS4 launcher + RS4 ring). + // + uint64_t scanChipletAddress=0; + uint32_t asmBuffer[ASM_RS4_LAUNCH_BUF_SIZE/4]; + PoreInlineContext ctx; + + FAPI_INF("XIPC: PLL update: Building the RS4 PLL ring block."); + // Reuse i_buf1 to hold the ring block. + bufPllRingAltBlock = (DeltaRingLayout*)i_buf1; + sizePllRingAltBlockMax = i_sizeBuf1; + + // Construct RS4 launcher: + // ...get the RS4 decompress address. + rcLoc = sbe_xip_get_scalar( o_imageOut, "proc_sbe_decompress_scan_chiplet_address", &scanChipletAddress); + if (rcLoc) { + FAPI_ERR("sbe_xip_get_scalar() failed w/rc=%i", rcLoc); + FAPI_ERR("Probable cause: Key word =proc_sbe_decompress_scan_chiplet_address not found in image."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (scanChipletAddress==0) { + FAPI_ERR("Value of key word (=proc_sbe_decompress_scan_chiplet_address=0) not permitted."); + uint64_t &DATA_RS4_DECOMPRESS_ADDR=scanChipletAddress; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_ILLEGAL_RS4_DECOMPRESS_ADDR); + return rc; + } + // ... create inline asm code. + pore_inline_context_create( &ctx, asmBuffer, ASM_RS4_LAUNCH_BUF_SIZE*4, 0, 0); + rcLoc = ctx.error; + if (rcLoc) { + FAPI_ERR("pore_inline_context_create() failed w/rc=%i", rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PORE_INLINE_CTX_CREATE_ERROR); + return rc; + } + pore_MR(&ctx, A0, PC); + pore_ADDS(&ctx, A0, A0, ASM_RS4_LAUNCH_BUF_SIZE); + pore_LI(&ctx, D0, scanChipletAddress); + pore_BRAD(&ctx, D0); + rcLoc = ctx.error; + if (rcLoc) { + FAPI_ERR("pore_MR/ADDS/LI/BRAD() failed w/rc=%i", rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PORE_INLINE_RS4_LAUNCH_CREATE_ERROR); + return rc; + } + sizeRs4Launch = ctx.lc; + + // Populate ring header and put ring header, RS4 launcher and RS4 ring into + // proper spots in pre-allocated bufPllRingAltBlock buffer. + // + uint64_t entryOffsetPllRingAltBlock; + uint32_t sizeOfThisPllRingAltBlock; + entryOffsetPllRingAltBlock = calc_ring_layout_entry_offset( 0, 0); + bufPllRingAltBlock->entryOffset = myRev64(entryOffsetPllRingAltBlock); + bufPllRingAltBlock->backItemPtr = 0; // Will be updated below, as we don't know yet. + sizeOfThisPllRingAltBlock = entryOffsetPllRingAltBlock + // Must be 8-byte aligned. + sizeRs4Launch + // Must be 8-byte aligned. + sizePllRingAltRs4; // Must be 8-byte aligned. + bufPllRingAltBlock->sizeOfThis = myRev32(sizeOfThisPllRingAltBlock); + // Quick check to see if final ring block size will fit in buf1. + if (sizeOfThisPllRingAltBlock>sizePllRingAltBlockMax) { + FAPI_ERR("PLL _alt ring block size (=%i) exceeds pre-allocated buf1 size (=%i).", + sizeOfThisPllRingAltBlock, sizePllRingAltBlockMax); + uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeOfThisPllRingAltBlock; + uint32_t &DATA_SIZE_OF_BUF1=sizePllRingAltBlockMax; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PLL_RING_BLOCK_TOO_LARGE); + return rc; + } + bufPllRingAltBlock->sizeOfMeta = 0; + bufPllRingAltBlock->ddLevel = myRev32((uint32_t)attrDdLevel); + bufPllRingAltBlock->sysPhase = i_sysPhase; + bufPllRingAltBlock->override = 0; + bufPllRingAltBlock->reserved1 = 0; + bufPllRingAltBlock->reserved2 = 0; + bufLC = (uint32_t)entryOffsetPllRingAltBlock; + // Copy over meta data which is zero, so nothing to do in this case! + // Copy over RS4 launch code which is [already] BE and 8-byte aligned. + memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, asmBuffer, (size_t)sizeRs4Launch); + // Copy over RS4 PLL _alt delta scan ring which is [already] 8-byte aligned. + bufLC = bufLC + sizeRs4Launch; + memcpy( (uint8_t*)bufPllRingAltBlock+bufLC, bufPllRingAltRs4, (size_t)sizePllRingAltRs4); + + // Now, some post-sanity checks on alignments. + if ( sizeRs4Launch!=ASM_RS4_LAUNCH_BUF_SIZE || + entryOffsetPllRingAltBlock%8 || + sizeRs4Launch%8 || + sizeOfThisPllRingAltBlock%8) { + FAPI_ERR("Member(s) of PLL _alt ring block are not 8-byte aligned:"); + FAPI_ERR(" Size of RS4 launch code = %i", sizeRs4Launch); + FAPI_ERR(" Entry offset = %i", (uint32_t)entryOffsetPllRingAltBlock); + FAPI_ERR(" Size of ring block = %i", sizeOfThisPllRingAltBlock); + uint32_t &DATA_SIZE_OF_RS4_LAUNCH=sizeRs4Launch; + tmp32Const1=(uint32_t)entryOffsetPllRingAltBlock; + uint32_t &DATA_RING_BLOCK_ENTRYOFFSET=tmp32Const1; + uint32_t &DATA_RING_BLOCK_SIZEOFTHIS=sizeOfThisPllRingAltBlock; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RING_BLOCK_ALIGN_ERROR); + return rc; + } + + + // + // Append PLL _alt ring to image. + // + SbeXipItem tocItem; + rcLoc = sbe_xip_find(o_imageOut, PB_BNDY_DMIPLL_RING_ALT_TOC_NAME, &tocItem); + if (rcLoc) + { + FAPI_INF("Skipping PLL update for %s", PB_BNDY_DMIPLL_RING_ALT_TOC_NAME); + rcLoc = 0; + } + else + { + FAPI_INF("XIPC: PLL update: Appending RS4 PLL ring block to .rings section."); + rcLoc = write_ring_block_to_image( o_imageOut, + PB_BNDY_DMIPLL_RING_ALT_TOC_NAME, + bufPllRingAltBlock, + 0, + 0, + 0, + largeSeeprom? sizeImageOutMax:MAX_SEEPROM_IMAGE_SIZE, // OK, since sysPhase=0. + SBE_XIP_SECTION_RINGS, + i_buf2, + i_sizeBuf2); + if (rcLoc) + { + FAPI_ERR("write_ring_block_to_image() failed for %s w/rc=%i", PB_BNDY_DMIPLL_RING_ALT_TOC_NAME, rcLoc); + FAPI_ERR("Check p8_delta_scan_rw.h for meaning of IMGBUILD_xyz rc code."); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } + } + } + +#endif + + +#ifndef IMGBUILD_PPD_IGNORE_VPD + // ========================================================================== + // CUSTOMIZE item: Add #G and #R rings. + // Retrieval method: MVPD + // System phase: Applies to both sysPhase modes: IPL and SLW. + // Notes: For SLW, only update ex_ chiplet rings. + // ========================================================================== + SbeXipSection xipSectionDcrings; + + // First, is there an .dcrings section yet in the input image? We need this to know + // if we should do datacare on #G rings a little later. + // (Note, it makes no sense checking in output image since SLW has been wiped clean, and + // the same may be the case with IPL image in the future.) + rcLoc = sbe_xip_get_section(i_imageIn, SBE_XIP_SECTION_DCRINGS, &xipSectionDcrings); + if (rcLoc) { + FAPI_ERR("_get_section(.dcrings...) failed with rc=%i ",rcLoc); + uint32_t &RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_IMGBUILD_ERROR); + return rc; + } + + if (i_sysPhase==0 && !largeSeeprom) { + // The .dcrings section will eventually be removed from the image, so set the + // max size to final output size max + .dcrings size if we can + sizeImageMax = min(MAX_SEEPROM_IMAGE_SIZE + xipSectionDcrings.iv_size, sizeImageOutMax); + } else { + sizeImageMax = sizeImageOutMax; + } + + // First, insert the chiplet XX rings + rc = p8_xip_customize_insert_chiplet_rings( i_target, + i_imageIn, + o_imageOut, + i_sysPhase, + i_buf1, + i_sizeBuf1, + i_buf2, + i_sizeBuf2, + attrDdLevel, + + sizeImageMax, + 0xFF, + xipSectionDcrings + ); + if (rc) return rc; + + // Then loop through the chiplets + uint32_t validEXCount = 0; + uint8_t chipletId; + io_bootCoreMask = 0; + for (chipletId = CHIPLET_ID_MIN; chipletId <= CHIPLET_ID_MAX; chipletId++) { + // Only process functional chiplets + // Note - currently the SBE treats bad cores (0x93) as non-functional (0x00) + // so inserting rings for those wastes space. I'll assume that they + // won't be in the desiredBootCoreMask and thus won't get rings, + // rather than checking for that case because the SBE code may change. + if (attrCombGoodVec[chipletId]) { + // Special handling for EX chiplet IDs + if ((chipletId >= CHIPLET_ID_EX_MIN) && (chipletId <= CHIPLET_ID_EX_MAX)) { + if (desiredBootCoreMask & (0x80000000 >> chipletId)) { + rc = p8_xip_customize_insert_chiplet_rings( i_target, + i_imageIn, + o_imageOut, + i_sysPhase, + i_buf1, + i_sizeBuf1, + i_buf2, + i_sizeBuf2, + attrDdLevel, + sizeImageMax, + chipletId, + xipSectionDcrings + ); + if (rc) { + // Check if this is just a case of trying to fit in too many EXs + if ((i_sysPhase == 0) && + (rc == RC_PROC_XIPC_RING_WRITE_WOULD_OVERFLOW)) + { + + uint32_t MINIMUM_VALID_EXS; + fapi::ReturnCode lrc; + lrc = FAPI_ATTR_GET(ATTR_SBE_IMAGE_MINIMUM_VALID_EXS, NULL, MINIMUM_VALID_EXS); + if (lrc) + { + FAPI_INF("Unable to determine ATTR_SBE_IMAGE_MINIMUM_VALID_EXS, so don't know if the minimum was met"); + fapiLogError(lrc); + uint32_t & VALID_COUNT = validEXCount; + uint32_t & MINIMUM = MINIMUM_VALID_EXS; + const uint32_t & DESIRED_CORES = desiredBootCoreMask; + uint32_t & BOOT_CORE_MASK = io_bootCoreMask; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_RING_WRITE_WOULD_OVERFLOW_ADD_INFO); + return rc; + } + + if (validEXCount < MINIMUM_VALID_EXS) { FAPI_ERR("Was only able to put %i EXs into the IPL image (minimum is %i)", validEXCount, MINIMUM_VALID_EXS); fapiLogError(rc); @@ -1398,6 +2333,89 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, } } + // ========================================================================== + // CUSTOMIZE item: intr_decrementer_delay* + // Retrieval method: Generated by this code + // System phase: IPL sysPhase. + // Note: Customizes SBE interrupt service + // ========================================================================== + if (i_sysPhase==0) { + // target delay cycles/us + void *hostDelayCycles; + uint32_t delay_cycles; + void *hostDelayUs; + uint32_t delay_us; + + // determine nest frequency + uint32_t freq_pb; + rc = FAPI_ATTR_GET(ATTR_FREQ_PB, NULL, freq_pb); + if (!rc.ok()) + { + FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_FREQ_PB)"); + return rc; + } + + // set attributes accordingly + delay_us = 10; + if (freq_pb == 2000) + { + delay_cycles = 0x1097; + } + else + { + delay_cycles = 0x1460; + } + rc = FAPI_ATTR_SET(ATTR_SBE_MASTER_INTR_SERVICE_DELAY_CYCLES, NULL, delay_cycles); + if (!rc.ok()) + { + FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_SBE_MASTER_INTR_SERVICE_DELAY_CYCLES)"); + return rc; + } + rc = FAPI_ATTR_SET(ATTR_SBE_MASTER_INTR_SERVICE_DELAY_US, NULL, delay_us); + if (!rc.ok()) + { + FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_SBE_MASTER_INTR_SERVICE_DELAY_US)"); + return rc; + } + + // customize image + rcLoc = sbe_xip_find(o_imageOut, INTR_DECREMENTER_DELAY_CYCLES_NAME, &xipTocItem); + if (rcLoc) + { + FAPI_INF("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_INF("Probable cause:"); + FAPI_INF("\tThe keyword (=%s) was not found.", INTR_DECREMENTER_DELAY_CYCLES_NAME); + rcLoc = 0; + } + else + { + sbe_xip_pore2host(o_imageOut, xipTocItem.iv_address, &hostDelayCycles); + FAPI_INF("Dumping [initial] global variable content of %s, then the updated value:\n", INTR_DECREMENTER_DELAY_CYCLES_NAME); + FAPI_INF(" Before=0x%016llX\n",myRev64(*(uint64_t*)hostDelayCycles)); + *(uint64_t*)hostDelayCycles = myRev64(delay_cycles); + FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostDelayCycles)); + } + + // delay in us + rcLoc = sbe_xip_find(o_imageOut, INTR_DECREMENTER_DELAY_US_NAME, &xipTocItem); + if (rcLoc) + { + FAPI_INF("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_INF("Probable cause:"); + FAPI_INF("\tThe keyword (=%s) was not found.", INTR_DECREMENTER_DELAY_US_NAME); + rcLoc = 0; + } + else + { + sbe_xip_pore2host(o_imageOut, xipTocItem.iv_address, &hostDelayUs); + FAPI_INF("Dumping [initial] global variable content of %s, then the updated value:\n", INTR_DECREMENTER_DELAY_US_NAME); + FAPI_INF(" Before=0x%016llX\n",myRev64(*(uint64_t*)hostDelayUs)); + *(uint64_t*)hostDelayUs = myRev64(delay_us); + FAPI_INF(" After =0x%016llX\n",myRev64(*(uint64_t*)hostDelayUs)); + } + } + + // ========================================================================== // CUSTOMIZE item: valid_boot_cores_mask // Retrieval method: Generated by this code diff --git a/src/usr/hwpf/hwp/build_winkle_images/proc_mailbox_utils/p8_mailbox_utils.C b/src/usr/hwpf/hwp/build_winkle_images/proc_mailbox_utils/p8_mailbox_utils.C index b43674a48..963ae13d8 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/proc_mailbox_utils/p8_mailbox_utils.C +++ b/src/usr/hwpf/hwp/build_winkle_images/proc_mailbox_utils/p8_mailbox_utils.C @@ -23,13 +23,12 @@ /* */ /* IBM_PROLOG_END_TAG */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: p8_mailbox_utils.C,v 1.7 2014/11/18 17:35:56 jmcgill Exp $ +// $Id: p8_mailbox_utils.C,v 1.10 2015/08/13 14:22:22 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_mailbox_utils.C,v $ //------------------------------------------------------------------------------ // *| // *! (C) Copyright International Business Machines Corp. 2012 // *! All Rights Reserved -- Property of IBM -// *! *** *** // *| // *! TITLE : proc_mailbox_utils.C // *! DESCRIPTION : Functions to calculate the mailbox values @@ -680,7 +679,9 @@ fapi::ReturnCode p8_mailbox_utils_get_mbox3( const fapi::Target &i_target, uint3 // 16:23 -> VCS voltage (1B in VRM-11 encoded form - 6.25mV increments) // note: VPD is in 5mV increments // -current recommended default = 0x4a -// 24:27 -> Unused = 0x00 +// 24 -> Force use of SBE scan service for slave chips +// 25 -> Skip use of SBE interrupt service on master chip +// 25:27 -> Unused = 0x0 // 28 -> Fabric wrap test = MNFG wrap test attribute // 29:31 -> Fabric node ID = Node ID attribute // @@ -697,6 +698,8 @@ fapi::ReturnCode p8_mailbox_utils_get_mbox4( const fapi::Target &i_target, uint3 const uint32_t BOOT_VOLTAGE_INFO_BIT_POSITION = 0; const uint32_t BOOT_VOLTAGE_INFO_BIT_LENGTH = 32; + const uint32_t FORCE_USE_SBE_SLAVE_SCAN_SERVICE = 24; + const uint32_t FORCE_SKIP_SBE_MASTER_INTR_SERVICE = 25; const uint32_t WRAP_TEST_BIT = 28; const uint32_t NODE_ID_BIT_POSITION = 29; const uint32_t NODE_ID_BIT_LENGTH = 3; @@ -755,8 +758,36 @@ fapi::ReturnCode p8_mailbox_utils_get_mbox4( const fapi::Target &i_target, uint3 FAPI_INF("Boot Voltage: VDD = %1.2f mV, VCS = %1.2f mV", (float)l_vdd_mv / 100, (float)l_vcs_mv / 100); + + fapi::ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE_Type force_use_scan_service = 0; + l_fapirc = FAPI_ATTR_GET(ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE, NULL, force_use_scan_service); + if (l_fapirc) + { + FAPI_ERR("fapiGetAttribute of ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE failed"); + break; + } + FAPI_INF( "ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE => %d", force_use_scan_service); + if (force_use_scan_service == fapi::ENUM_ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE_TRUE) + { + o_set_data |= 1 << (sizeof(o_set_data)*8 - FORCE_USE_SBE_SLAVE_SCAN_SERVICE - 1); + } + + fapi::ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE_Type force_skip_intr_service = 0; + l_fapirc = FAPI_ATTR_GET(ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE, NULL, force_skip_intr_service); + if (l_fapirc) + { + FAPI_ERR("fapiGetAttribute of ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE failed"); + break; + } + FAPI_INF( "ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE => %d", force_skip_intr_service); + if (force_skip_intr_service == fapi::ENUM_ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE_TRUE) + { + o_set_data |= 1 << (sizeof(o_set_data)*8 - FORCE_SKIP_SBE_MASTER_INTR_SERVICE - 1); + } + if (i_write_fbc_data) { + // set wrap test flag (FSP boot) fapi::ATTR_MNFG_FLAGS_Type l_mnfg_flags = 0; l_fapirc = FAPI_ATTR_GET( ATTR_MNFG_FLAGS, @@ -776,7 +807,7 @@ fapi::ReturnCode p8_mailbox_utils_get_mbox4( const fapi::Target &i_target, uint3 { FAPI_ERR("fapiGetAttribute of ATTR_CHIP_EC_FEATURE_SET_LEGACY_NODE_ID_VALID_MBOX_BIT failed"); break; - } + } if (((l_mnfg_flags & fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_BRAZOS_WRAP_CONFIG) == fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_BRAZOS_WRAP_CONFIG) || diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C index c5e25d2f0..b8b01ed5f 100644 --- a/src/usr/hwpf/hwp/core_activate/core_activate.C +++ b/src/usr/hwpf/hwp/core_activate/core_activate.C @@ -288,9 +288,11 @@ void* call_host_activate_master( void *io_pArgs ) TARGETING::get_huid(l_cpu_target) ); // call the HWP with each fapi::Target + bool l_sbeIntrServiceActive = false; FAPI_INVOKE_HWP( l_errl, proc_stop_deadman_timer, - l_fapi_cpu_target ); + l_fapi_cpu_target, + l_sbeIntrServiceActive ); if ( l_errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, @@ -308,6 +310,10 @@ void* call_host_activate_master( void *io_pArgs ) TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "proc_prep_master_winkle SUCCESS" ); } + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + sys->setAttr + (l_sbeIntrServiceActive); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Enable special wakeup on master core"); diff --git a/src/usr/hwpf/hwp/core_activate/makefile b/src/usr/hwpf/hwp/core_activate/makefile index 40ce20f6f..2ef737fc4 100644 --- a/src/usr/hwpf/hwp/core_activate/makefile +++ b/src/usr/hwpf/hwp/core_activate/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2012,2014 +# Contributors Listed Below - COPYRIGHT 2012,2015 # [+] International Business Machines Corp. # # @@ -61,6 +61,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp/utility_procedures OBJS += core_activate.o OBJS += proc_prep_master_winkle.o OBJS += proc_stop_deadman_timer.o +OBJS += proc_sbe_utils.o OBJS += proc_switch_cfsim.o OBJS += proc_switch_rec_attn.o OBJS += cen_switch_rec_attn.o diff --git a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_intr_service.H b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_intr_service.H new file mode 100644 index 000000000..feae59ddb --- /dev/null +++ b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_intr_service.H @@ -0,0 +1,39 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_intr_service.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_sbe_intr_service.H,v 1.2 2015/07/27 00:28:05 jmcgill Exp $ + +/// Substep numbers for the proc_sbe_intr_service procedure + +#ifndef __PROC_SBE_INTR_SERVICE_H +#define __PROC_SBE_INTR_SERVICE_H + +#include "fapi_sbe_common.H" +#include "sbe_vital.H" + +//NOTE: The following values must stay constant as HB looks for them +CONST_UINT8_T(PROC_SBE_INTR_SERVICE_SUBSTEP_SBE_READY, ULL(0x1)); +CONST_UINT8_T(PROC_SBE_INTR_SERVICE_SUBSTEP_HALT_SUCCESS, ULL(0xF)); + +#endif // __PROC_SBE_INTR_SERVICE_H diff --git a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.C b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.C new file mode 100644 index 000000000..8bfebd193 --- /dev/null +++ b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.C @@ -0,0 +1,237 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_sbe_utils.C,v 1.1 2015/07/27 00:39:15 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_sbe_utils.C,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_sbe_utils.C +// *! DESCRIPTION : SBE utility functions +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ +const uint8_t SBE_STOPPED_AT_BREAKPOINT_0xB = 0xB; + + +//------------------------------------------------------------------------------ +// Function definitions +//------------------------------------------------------------------------------ +extern "C" +{ + + +fapi::ReturnCode proc_sbe_utils_reset_sbe( + const fapi::Target & i_target) +{ + ecmdDataBufferBase sbe_reset_data(64); + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; + + do + { + rc_ecmd |= sbe_reset_data.flushTo0(); + rc_ecmd |= sbe_reset_data.setBit(0); + + if (rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom(i_target, PORE_SBE_RESET_0x000E0002, sbe_reset_data); + if (!rc.ok()) + { + FAPI_ERR("Scom error resetting SBE"); + break; + } + } while(0); + + return rc; +} + + +fapi::ReturnCode proc_sbe_utils_update_substep( + const fapi::Target & i_target, + uint8_t i_substep_num) +{ + // data buffer to hold register values + ecmdDataBufferBase sbe_vital_data(64); + + // return codes + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; + + do + { + // read SBE Vital register + FAPI_DBG("Checking SBE Vital register"); + rc = fapiGetScom(i_target, MBOX_SBEVITAL_0x0005001C, sbe_vital_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Vital register"); + break; + } + + rc_ecmd |= sbe_vital_data.insertFromRight(&i_substep_num, + SUBSTEP_NUM_BIT_POSITION, + SUBSTEP_NUM_BIT_LENGTH); + if (rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom(i_target, MBOX_SBEVITAL_0x0005001C, sbe_vital_data); + if(!rc.ok()) + { + FAPI_ERR("Error updating SBE Vital register"); + break; + } + } while(0); + + return(rc); +} + + + +fapi::ReturnCode proc_sbe_utils_check_status( + const fapi::Target & i_target, + bool & o_running, + uint8_t & o_halt_code, + uint16_t & o_istep_num, + uint8_t & o_substep_num) +{ + // data buffer to hold register values + ecmdDataBufferBase sbe_vital_data(64); + ecmdDataBufferBase sbe_control_data(64); + ecmdDataBufferBase sbe_status_data(64); + + // return codes + uint32_t rc_ecmd = 0; + fapi::ReturnCode rc; + + do + { + // read SBE Control register + FAPI_DBG("Checking SBE Control register"); + rc = fapiGetScom(i_target, PORE_SBE_CONTROL_0x000E0001, sbe_control_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Control register"); + break; + } + + // Bit 0 : 1=stopped, 0=running (or stopped at breakpoint) + if (sbe_control_data.isBitClear(0)) + { + o_running = true; + + // if running, check for stopped at breakpoint + FAPI_DBG("Checking SBE Status register"); + rc = fapiGetScom(i_target, PORE_SBE_STATUS_0x000E0000, sbe_status_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Status register"); + break; + } + + uint8_t state = 0; + uint64_t address = sbe_status_data.getDoubleWord(0) & 0x0000FFFFFFFFFFFFULL; + rc_ecmd |= sbe_status_data.extractToRight(&state, 3, 4); + if (rc_ecmd) + { + FAPI_ERR("Error (0x%x) extracting data from SBE Status data buffer", + rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + if (state == SBE_STOPPED_AT_BREAKPOINT_0xB) + { + FAPI_INF("SBE stopped at breakpoint (address 0x%012llX)", + address); + o_running = false; + break; + } + } + else + { + o_running = false; + } + + // read SBE Vital register + FAPI_DBG("Checking SBE Vital register"); + rc = fapiGetScom(i_target, MBOX_SBEVITAL_0x0005001C, sbe_vital_data); + if (!rc.ok()) + { + FAPI_ERR("Error reading SBE Vital register"); + break; + } + + // parse out halt code & istep progress information + o_halt_code = 0; + o_istep_num = 0; + o_substep_num = 0; + rc_ecmd |= sbe_vital_data.extractToRight(&o_halt_code, + HALT_CODE_BIT_POSITION, + HALT_CODE_BIT_LENGTH); + rc_ecmd |= sbe_vital_data.extractToRight(&o_istep_num, + ISTEP_NUM_BIT_POSITION, + ISTEP_NUM_BIT_LENGTH); + rc_ecmd |= sbe_vital_data.extractToRight(&o_substep_num, + SUBSTEP_NUM_BIT_POSITION, + SUBSTEP_NUM_BIT_LENGTH); + if (rc_ecmd) + { + FAPI_ERR("Error (0x%x) extracting data from SBE Vital data buffer", + rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + + } while(0); + + return rc; +} + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.H b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.H new file mode 100644 index 000000000..4a45dc95a --- /dev/null +++ b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.H @@ -0,0 +1,96 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_sbe_utils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_sbe_utils.H,v 1.1 2015/07/27 00:39:15 jmcgill Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_sbe_utils.H,v $ +//------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2015 +// *! All Rights Reserved -- Property of IBM +// *! *** *** +// *| +// *! TITLE : proc_sbe_utils.H +// *! DESCRIPTION : SBE utility functions +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! +//------------------------------------------------------------------------------ + +#ifndef _PROC_SBE_UTILS_H_ +#define _PROC_SBE_UTILS_H_ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +extern "C" +{ + + +/** + * @brief Reset SBE engine + * + * @param[in] i_target Reference to chip target + * @return ReturnCode + */ +fapi::ReturnCode proc_sbe_utils_reset_sbe( + const fapi::Target & i_target); + +/** + * @brief Update SBE Vital register with substep progress code + * + * @param[in] i_target Reference to chip target + * @param[in] i_substep_num Substep progress code to write + * @return ReturnCode + */ +fapi::ReturnCode proc_sbe_utils_update_substep( + const fapi::Target & i_target, + uint8_t i_substep_num); + +/** + * @brief Determine SBE run state and istep progress + * + * @param[in] i_target Reference to chip target + * @param[out] o_running Is SBE running or stopped? + * @param[out] o_halt_code SBE halt code (only valid if SBE stopped) + * @param[out] o_istep_num Current istep number (0xMmm) + * @param[out] o_substep_num Current substep within istep + * @return ReturnCode + */ +fapi::ReturnCode proc_sbe_utils_check_status( + const fapi::Target & i_target, + bool & o_running, + uint8_t & o_halt_code, + uint16_t & o_istep_num, + uint8_t & o_substep_num); + + +} // extern "C" + +#endif // _PROC_SBE_UTILS_H_ diff --git a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.C b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.C index f203406fb..32f38f971 100644 --- a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.C +++ b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -23,7 +23,7 @@ /* */ /* IBM_PROLOG_END_TAG */ // -*- mode: C++; c-file-style: "linux"; -*- -// $Id: proc_stop_deadman_timer.C,v 1.10 2014/02/10 04:40:32 stillgs Exp $ +// $Id: proc_stop_deadman_timer.C,v 1.14 2015/08/04 19:56:09 thi Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_stop_deadman_timer.C,v $ //------------------------------------------------------------------------------ // *| @@ -32,14 +32,14 @@ // *! *** *** // *| // *! TITLE : proc_stop_deadman_timer.C -// *! DESCRIPTION : Stops deadman timer and SBE +// *! DESCRIPTION : Stops deadman timer // *! // *! OWNER NAME : Greg Still Email: stillgs@us.ibm.com // *! // *! Overview: // *! Notify SBE that HB is alive again -// *! Make sure SBE stopped -// *! +// *! Conditionally stop the SBE +// *! // *! Here's the flow of SBE_VITAL substeps: // *! SBE (automatic on procedure entry): substep_proc_entry // *! SBE : substep_sbe_ready @@ -58,6 +58,21 @@ #include #include #include +#include +#include + + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ +const uint64_t NS_TO_FINISH = 10000000; //(10 ms) +const uint64_t MS_TO_FINISH = NS_TO_FINISH/1000000; +const uint64_t SIM_CYCLES_TO_FINISH = 10000000; + +const uint64_t MAX_WAIT_TIME_MS = 1000; + +const uint8_t SBE_EXIT_SUCCESS_0xF = 0xF; + //------------------------------------------------------------------------------ // Function definitions @@ -66,147 +81,227 @@ extern "C" { +fapi::ReturnCode proc_stop_deadman_timer(const fapi::Target & i_target, + bool & o_intr_service_running) +{ + // return codes + fapi::ReturnCode rc; + uint32_t rc_ecmd = 0; + + // mark function entry + FAPI_INF("Start"); -//------------------------------------------------------------------------------ -// function: proc_stop_deadman_timer -// Notify SBE that HB is alive again -// Force the SBE to stop running -// -// parameters: i_target => chip target -// returns: FAPI_RC_SUCCESS if operation was successful, else error -//------------------------------------------------------------------------------ - fapi::ReturnCode proc_stop_deadman_timer(const fapi::Target & i_target) + do { - // data buffer to hold register values - ecmdDataBufferBase data(64); + // + // check SBE progress + // - // return codes - uint32_t rc_ecmd = 0; - fapi::ReturnCode rc; + // given this procedure is running, the SBE deadman function should have worked + // check that the SBE VITAL reached the correct spot + bool sbe_running; + size_t loop_time = 0; + uint8_t halt_code; + uint16_t istep_num; + uint8_t substep_num; + bool intr_service_loop_reached = false; + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_check_sbe_state_check_status"); + break; + } + + if (!(sbe_running && + !halt_code && + (istep_num == proc_sbe_trigger_winkle_istep_num) && + (substep_num == SUBSTEP_DEADMAN_WAITING_FOR_HOSTBOOT))) + { + FAPI_ERR("Expected istep/substep num %llX/%X but found %X/%X", + proc_sbe_trigger_winkle_istep_num, + SUBSTEP_DEADMAN_WAITING_FOR_HOSTBOOT, + istep_num, + substep_num); + const fapi::Target & CHIP_IN_ERROR = i_target; + const bool & SBE_RUNNING = sbe_running; + const uint8_t & HALT_CODE = halt_code; + const uint16_t & ISTEP_NUM = istep_num; + const uint8_t & SUBSTEP_NUM = substep_num; + FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_DEADMAN_TIMER_UNEXPECTED_INITIAL_STATE); + fapiLogError(rc); + } + + // + // send SBE message -- HOSTBOOT_ALIVE_AGAIN + // + + rc = proc_sbe_utils_update_substep( + i_target, + SUBSTEP_HOSTBOOT_ALIVE_AGAIN); + if (!rc.ok()) + { + FAPI_ERR("Error from proc_sbe_utils_update_substep"); + break; + } - // mark function entry - FAPI_INF("Entry new\n"); + // + // Loop until: + // SBE stopped OR + // interrupt serivce ready loop is reached OR + // loop time is exceeded + // - do + while (sbe_running && + !intr_service_loop_reached && + (loop_time < MAX_WAIT_TIME_MS)) { - // Given this procedure is running, the SBE deadman function did - // its job. Check that for the SBE_VITAL being at the correct spot - rc = fapiGetScom(i_target, MBOX_SBEVITAL_0x0005001C, data); - if(!rc.ok()) + // sleep 10ms, then check again + loop_time += MS_TO_FINISH; + rc = fapiDelay(NS_TO_FINISH, SIM_CYCLES_TO_FINISH); + if (rc) { - FAPI_ERR("Scom error reading SBE VITAL\n"); + FAPI_ERR("Error from fapiDelay"); break; } - uint32_t istep_num = 0; - uint8_t substep_num = 0; - rc_ecmd |= data.extractToRight(&istep_num, - ISTEP_NUM_BIT_POSITION, - ISTEP_NUM_BIT_LENGTH); - rc_ecmd |= data.extractToRight(&substep_num, - SUBSTEP_NUM_BIT_POSITION, - SUBSTEP_NUM_BIT_LENGTH); - if(rc_ecmd) + // retrieve status + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); - rc.setEcmdError(rc_ecmd); + FAPI_ERR("Error from proc_check_sbe_state_check_status"); break; } - if( istep_num != proc_sbe_trigger_winkle_istep_num ) - { - FAPI_ERR("Expected istep num %llX but found %X\n", - proc_sbe_trigger_winkle_istep_num, - istep_num ); - const fapi::Target & CHIP_IN_ERROR = i_target; - ecmdDataBufferBase & SBE_VITAL = data; - FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_DEADMAN_TIMER_BAD_ISTEP_NUM); - fapiLogError(rc); - } + intr_service_loop_reached = + sbe_running && + !halt_code && + (istep_num == PROC_SBE_INTR_SERVICE_ISTEP_NUM) && + (substep_num == SUBSTEP_SBE_READY); + } - if( substep_num != SUBSTEP_DEADMAN_WAITING_FOR_HOSTBOOT ) - { - FAPI_ERR("Expected substep num %X but found %X\n", - SUBSTEP_DEADMAN_WAITING_FOR_HOSTBOOT, - substep_num ); - const fapi::Target & CHIP_IN_ERROR = i_target; - ecmdDataBufferBase & SBE_VITAL = data; - FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_DEADMAN_TIMER_BAD_SUBSTEP_NUM); - fapiLogError(rc); - } + // break if we took an error in the while loop + if (rc) + { + break; + } + + FAPI_INF("SBE is running [%d], loop time [%zd], interrupt service loop reached [%d]", + sbe_running, loop_time, intr_service_loop_reached); - //Notify SBE that HB is alive again - substep_num = SUBSTEP_HOSTBOOT_ALIVE_AGAIN; - rc_ecmd |= data.insertFromRight(&substep_num, - SUBSTEP_NUM_BIT_POSITION, - SUBSTEP_NUM_BIT_LENGTH); - if(rc_ecmd) + // ensure correct halt code is captured + if (!sbe_running) + { + rc = proc_sbe_utils_check_status( + i_target, + sbe_running, + halt_code, + istep_num, + substep_num); + if (!rc.ok()) { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); - rc.setEcmdError(rc_ecmd); + FAPI_ERR("Error from proc_check_sbe_state_check_status"); break; } - rc = fapiPutScom(i_target, MBOX_SBEVITAL_0x0005001C, data); - if(!rc.ok()) + } + + // handle three valid possibilities: + // 1) SBE stopped at end of deadman timer routine (SBE code supports interrupt service, but the service is not enabled) + // 2) SBE is running interrupt service routine (SBE code supports interrupt service, and the service is enabled) + // 3) SBE is still running deadman timer routine (SBE code does not support interrupt service) + // If not in one of those 3 expected states, error out + if (!sbe_running && + (halt_code == SBE_EXIT_SUCCESS_0xF) && + (istep_num == proc_sbe_trigger_winkle_istep_num) && + (substep_num == SUBSTEP_HOSTBOOT_ALIVE_AGAIN)) + { + FAPI_INF("SBE halted at end of deadman timer routine, interrupt service is NOT running!"); + o_intr_service_running = false; + + // reset the SBE so it can be used for MPIPL if needed + rc = proc_sbe_utils_reset_sbe(i_target); + if (!rc.ok()) { - FAPI_ERR("Scom error updating SBE VITAL\n"); + FAPI_ERR("Error from proc_sbe_utils_reset_sbe"); break; } + } + else if (intr_service_loop_reached) + { + FAPI_INF("SBE finished deadman timer routine, interrupt service is running!"); + o_intr_service_running = true; + } + else if ( (sbe_running) && + (istep_num == proc_sbe_trigger_winkle_istep_num) && + (substep_num == SUBSTEP_HOSTBOOT_ALIVE_AGAIN) ) + + { + FAPI_INF("SBE is still running but not SBE interrupt. Stop and " + "reset the SBE!"); - // Stop SBE if needed + // Stop the SBE + ecmdDataBufferBase data(64); rc = fapiGetScom(i_target, PORE_SBE_CONTROL_0x000E0001, data); - if(!rc.ok()) + if (!rc.ok()) { - FAPI_ERR("Scom error reading SBE STATUS\n"); + FAPI_ERR("Error returned from fapiGetScom, addr 0x%.16llX ", + PORE_SBE_CONTROL_0x000E0001); break; } - if( data.isBitSet( 0 ) ) + rc_ecmd |= data.setBit( 0 ); + if (rc_ecmd) { - FAPI_INF("SBE/Deadman timer successfully stopped\n"); + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); + rc.setEcmdError(rc_ecmd); break; } - else - { - rc_ecmd |= data.setBit( 0 ); - if(rc_ecmd) - { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); - rc.setEcmdError(rc_ecmd); - break; - } - rc = fapiPutScom(i_target, PORE_SBE_CONTROL_0x000E0001, data); - if(!rc.ok()) - { - FAPI_ERR("Scom error stopping SBE\n"); - break; - } - } - - // Reset the SBE so it can be used for MPIPL if needed - rc_ecmd |= data.flushTo0(); - rc_ecmd |= data.setBit(0); - if(rc_ecmd) + rc = fapiPutScom(i_target, PORE_SBE_CONTROL_0x000E0001, data); + if ( !rc.ok() ) { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd); - rc.setEcmdError(rc_ecmd); + FAPI_ERR("Error returned from fapiPutScom to stop " + "SBE, addr 0x%.16llX", PORE_SBE_CONTROL_0x000E0001); break; } - rc = fapiPutScom(i_target, PORE_SBE_RESET_0x000E0002, data); - if(!rc.ok()) + + // Reset the SBE + rc = proc_sbe_utils_reset_sbe(i_target); + if (!rc.ok()) { - FAPI_ERR("Scom error resetting SBE\n"); + FAPI_ERR("Error from proc_sbe_utils_reset_sbe"); break; } - - } while (0); - // mark function exit - FAPI_INF("Exit"); - return rc; - } + // Set flag to indicate SBE interrupt is not running + o_intr_service_running = false; + } + // error + else + { + FAPI_ERR("SBE did not reach acceptable final state!"); + const fapi::Target & CHIP_IN_ERROR = i_target; + const bool & SBE_RUNNING = sbe_running; + const uint8_t & HALT_CODE = halt_code; + const uint16_t & ISTEP_NUM = istep_num; + const uint8_t & SUBSTEP_NUM = substep_num; + FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_DEADMAN_TIMER_UNEXPECTED_FINAL_STATE); + break; + } + + } while (0); + + // mark function exit + FAPI_INF("Exit"); + return rc; +} } // extern "C" -/* Local Variables: */ -/* c-basic-offset: 4 */ -/* End: */ diff --git a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.H b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.H index a6f744eec..2db6de18b 100644 --- a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.H +++ b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: proc_stop_deadman_timer.H,v 1.3 2014/02/10 04:40:34 stillgs Exp $ +// $Id: proc_stop_deadman_timer.H,v 1.4 2015/07/27 00:44:20 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_stop_deadman_timer.H,v $ //------------------------------------------------------------------------------ // *| @@ -31,7 +31,7 @@ // *! *** *** // *| // *! TITLE : proc_stop_deadman_timer.H -// *! DESCRIPTION : Stops deadman timer and SBE +// *! DESCRIPTION : Stops deadman timer // *! // *! OWNER NAME : Greg Still Email: stillgs@us.ibm.com // *! @@ -51,11 +51,8 @@ //------------------------------------------------------------------------------ // function pointer typedef definition for HWP call support -typedef fapi::ReturnCode (*proc_stop_deadman_timer_FP_t)(const fapi::Target &); - -//------------------------------------------------------------------------------ -// Constant definitions -//------------------------------------------------------------------------------ +typedef fapi::ReturnCode (*proc_stop_deadman_timer_FP_t)(const fapi::Target &, + bool &); //------------------------------------------------------------------------------ // Function prototypes @@ -66,13 +63,15 @@ extern "C" { /** - * @brief Stop the deadman timer and the SBE + * @brief Stop the deadman timer * * @param[in] i_target Reference to chip target + * @param[out] o_intr_service_running Indicates state of interrupt service * * @return ReturnCode */ - fapi::ReturnCode proc_stop_deadman_timer(const fapi::Target & i_target); +fapi::ReturnCode proc_stop_deadman_timer(const fapi::Target & i_target, + bool & o_intr_service_running); } // extern "C" diff --git a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer_errors.xml b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer_errors.xml index 7f2b42fe4..8564800bd 100644 --- a/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer_errors.xml +++ b/src/usr/hwpf/hwp/core_activate/proc_stop_deadman_timer/proc_stop_deadman_timer_errors.xml @@ -5,7 +5,9 @@ - + + + @@ -20,15 +22,15 @@ - + - RC_PROC_STOP_DEADMAN_TIMER_BAD_ISTEP_NUM + RC_PROC_STOP_DEADMAN_TIMER_UNEXPECTED_INITIAL_STATE Procedure: proc_stop_deadman_timer - The SBE is not at the correct istep number to stop the deadman timer + The SBE did not reach the correct istep progress to stop the deadman timer REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS @@ -45,20 +47,23 @@ CHIP_IN_ERROR TARGET_TYPE_EX_CHIPLET 0x01000000 - + - SBE_VITAL + SBE_RUNNING + HALT_CODE + ISTEP_NUM + SUBSTEP_NUM - CODE + CODE HIGH - RC_PROC_STOP_DEADMAN_TIMER_BAD_SUBSTEP_NUM + RC_PROC_STOP_DEADMAN_TIMER_UNEXPECTED_FINAL_STATE Procedure: proc_stop_deadman_timer - The SBE is not at the correct substep number to stop the deadman timer + The SBE reached an unexpected final state REG_FFDC_PROC_STATUS_AND_SBE_VITAL_REGISTERS @@ -75,12 +80,16 @@ CHIP_IN_ERROR TARGET_TYPE_EX_CHIPLET 0x01000000 - + - SBE_VITAL + SBE_RUNNING + HALT_CODE + ISTEP_NUM + SUBSTEP_NUM - CODE + CODE HIGH + diff --git a/src/usr/hwpf/hwp/include/p8_istep_num.H b/src/usr/hwpf/hwp/include/p8_istep_num.H index 93b77b65c..b30396074 100644 --- a/src/usr/hwpf/hwp/include/p8_istep_num.H +++ b/src/usr/hwpf/hwp/include/p8_istep_num.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -23,7 +25,7 @@ #ifndef __P8_ISTEP_NUM_H #define __P8_ISTEP_NUM_H -// $Id: p8_istep_num.H,v 1.26 2013/10/03 20:52:47 jeshua Exp $ +// $Id: p8_istep_num.H,v 1.29 2015/05/28 20:45:55 jmcgill Exp $ /// Istep number encoding for all SEEPROM and PNOR procedures. Used to update /// the SBEVITAL register to record procedure progress and to create unique @@ -35,15 +37,15 @@ CONST_UINT64_T(proc_sbe_security_setup_istep_num, ULL(0x0201)); CONST_UINT64_T(proc_sbe_standalone_setup_istep_num, ULL(0x0202)); CONST_UINT64_T(proc_sbe_tp_chiplet_init1_istep_num, ULL(0x0203)); CONST_UINT64_T(proc_sbe_tp_ld_image_istep_num, ULL(0x0204)); -CONST_UINT64_T(proc_sbe_nest_skewadjust_istep_num, ULL(0x0205)); -CONST_UINT64_T(proc_sbe_npll_initf_istep_num, ULL(0x0206)); -CONST_UINT64_T(proc_sbe_npll_setup_istep_num, ULL(0x0207)); -CONST_UINT64_T(proc_sbe_tp_switch_gears_istep_num, ULL(0x0208)); -CONST_UINT64_T(proc_sbe_tp_chiplet_init2_istep_num, ULL(0x0209)); -CONST_UINT64_T(proc_sbe_tp_arrayinit_istep_num, ULL(0x020A)); -CONST_UINT64_T(proc_sbe_tp_initf_istep_num, ULL(0x020B)); -CONST_UINT64_T(proc_sbe_tp_chiplet_init3_istep_num, ULL(0x020C)); -CONST_UINT64_T(proc_sbe_chiplet_init_istep_num, ULL(0x020D)); +CONST_UINT64_T(proc_sbe_npll_initf_istep_num, ULL(0x0205)); +CONST_UINT64_T(proc_sbe_npll_setup_istep_num, ULL(0x0206)); +CONST_UINT64_T(proc_sbe_tp_switch_gears_istep_num, ULL(0x0207)); +CONST_UINT64_T(proc_sbe_tp_chiplet_init2_istep_num, ULL(0x0208)); +CONST_UINT64_T(proc_sbe_tp_arrayinit_istep_num, ULL(0x0209)); +CONST_UINT64_T(proc_sbe_tp_initf_istep_num, ULL(0x020A)); +CONST_UINT64_T(proc_sbe_tp_chiplet_init3_istep_num, ULL(0x020B)); +CONST_UINT64_T(proc_sbe_chiplet_init_istep_num, ULL(0x020C)); +CONST_UINT64_T(proc_sbe_nest_skewadjust_istep_num, ULL(0x020D)); CONST_UINT64_T(proc_sbe_arrayinit_istep_num, ULL(0x020E)); CONST_UINT64_T(proc_sbe_setup_evid_istep_num, ULL(0x020F)); CONST_UINT64_T(proc_sbe_initf_istep_num, ULL(0x0210)); @@ -82,6 +84,8 @@ CONST_UINT64_T(proc_sbe_instruct_start_istep_num, ULL(0x0502)); //NOTE: The following values must stay constant as HB looks for them CONST_UINT64_T(proc_sbe_trigger_winkle_istep_num, ULL(0x0F01)); +CONST_UINT64_T(proc_sbe_scan_service_istep_num, ULL(0x0FA0)); +CONST_UINT64_T(proc_sbe_intr_service_istep_num, ULL(0x0FB0)); CONST_UINT64_T(proc_sbe_check_master_magic_istep_num, ULL(0x02FF)); CONST_UINT64_T(proc_sbe_ex_host_runtime_scom_magic_istep_num,ULL(0x04FF)); CONST_UINT64_T(proc_sbe_enable_pnor_magic_istep_num, ULL(0x05FF)); @@ -107,6 +111,7 @@ CONST_UINT64_T(slw_deep_winkle_exit_istep_num, ULL(0x0F87)); #define PROC_SBE_EX_HOST_RUNTIME_SCOM_ISTEP_NUM proc_sbe_ex_host_runtime_scom_istep_num #define PROC_SBE_EX_HOST_RUNTIME_SCOM_MAGIC_ISTEP_NUM proc_sbe_ex_host_runtime_scom_magic_istep_num #define PROC_SBE_TP_LD_IMAGE_ISTEP_NUM proc_sbe_tp_ld_image_istep_num - +#define PROC_SBE_SCAN_SERVICE_ISTEP_NUM proc_sbe_scan_service_istep_num +#define PROC_SBE_INTR_SERVICE_ISTEP_NUM proc_sbe_intr_service_istep_num #endif // __P8_ISTEP_NUM_H diff --git a/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C b/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C index 42a276cf8..c74402df3 100644 --- a/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C +++ b/src/usr/hwpf/hwp/slave_sbe/slave_sbe.C @@ -174,6 +174,13 @@ void* call_host_slave_sbe_config(void *io_pArgs) errlCommit( l_errl, HWPF_COMP_ID ); } + + // Enable SBE interrupt for OP systems + TARGETING::Target* l_sys = NULL; + targetService().getTopLevelTarget(l_sys); + assert( l_sys != NULL ); + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Enabling SBE interrupt for OP systems"); + l_sys->setAttr(0); } // Resolve the side characteristics of the Processor SBE Seeproms diff --git a/src/usr/hwpf/hwp/system_attributes.xml b/src/usr/hwpf/hwp/system_attributes.xml index da015fe80..9181f2c3d 100644 --- a/src/usr/hwpf/hwp/system_attributes.xml +++ b/src/usr/hwpf/hwp/system_attributes.xml @@ -22,7 +22,7 @@ - + -    ATTR_REDUNDANT_CLOCKS -    TARGET_TYPE_SYSTEM -    -      1 = System has redundant clock oscillators - 0 = System does not have redundant clock oscillators - From the Machine Readable Workbook -    -    uint8 -    - -    ATTR_MFG_TRACE_ENABLE -    TARGET_TYPE_SYSTEM -    - Override this to a non-zero value to have the FAPI manufacturing - traces output to the console or go to a fsp trace buffer when - console not enabled. - In cronus, setting this to a non-zero will output the FAPI_MFG - traces to the same location as your other FAPI traces. -    -    uint8 -    + + ATTR_REDUNDANT_CLOCKS + TARGET_TYPE_SYSTEM + + 1 = System has redundant clock oscillators + 0 = System does not have redundant clock oscillators + From the Machine Readable Workbook + + uint8 + + + + + ATTR_MFG_TRACE_ENABLE + TARGET_TYPE_SYSTEM + + Override this to a non-zero value to have the FAPI manufacturing + traces output to the console or go to a fsp trace buffer when + console not enabled. + In cronus, setting this to a non-zero will output the FAPI_MFG + traces to the same location as your other FAPI traces. + + uint8 + + + + + ATTR_WOF_ENABLED + TARGET_TYPE_SYSTEM + + Defines if the Workload Optimization Frequency (WOF) system feature + where OCC algorithms will change (typically boost) the operational + frequency based on measured power available and any currently idling + cores. + + uint8 + + DISABLED = 0x0, + ENABLED = 0x1 + + + + + + ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE + TARGET_TYPE_SYSTEM + + Set to force use of SBE scan service for slave chips. + Default is to enable the use of the SBE scan service + only for slave chips with security enabled. + + uint8 + FALSE = 0, TRUE = 1 + + + + + + ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE + TARGET_TYPE_SYSTEM + + Set to indicate state of master->slave scan path. + Platform should default to false at beginning of IPL, and set to + true once trusted XSCOM path is active to all slave chips in drawer + + uint8 + FALSE = 0, TRUE = 1 + + + + + + ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE + TARGET_TYPE_SYSTEM + + Set to force skip of SBE interrupt service for master chip. + Default is to enable the use of the SBE interrupt service. + + uint8 + FALSE = 0, TRUE = 1 + + + + + + ATTR_SBE_MASTER_INTR_SERVICE_DELAY_CYCLES + TARGET_TYPE_SYSTEM + + Cycle delay of SBE master interrupt service loop wait statement. + Paces rate of decrementer progress and prevents SBE from consuming PIB. + + uint32 + + + + + ATTR_SBE_MASTER_INTR_SERVICE_DELAY_US + TARGET_TYPE_SYSTEM + + Execution delay (in microseconds) of SBE master interrupt service loop. + + uint32 + + diff --git a/src/usr/i2c/runtime/rt_i2c.C b/src/usr/i2c/runtime/rt_i2c.C index 8704b6be1..a74bb5dd0 100755 --- a/src/usr/i2c/runtime/rt_i2c.C +++ b/src/usr/i2c/runtime/rt_i2c.C @@ -149,51 +149,46 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, proc_engine_port |= (uint64_t)(args.port) << HBRT_I2C_MASTER_PORT_SHIFT; // Send I2C op to host interface - // Centaur I2C not yet supported - // @todo RTC:127533 -- Enable Centaur I2C at runtime - if( i_target->getAttr() != TARGETING::TYPE_MEMBUF ) + if(i_opType == DeviceFW::READ) { - if(i_opType == DeviceFW::READ) + if(g_hostInterfaces->i2c_read != NULL) { - if(g_hostInterfaces->i2c_read != NULL) - { - rc = g_hostInterfaces->i2c_read - ( - proc_engine_port, // Master Chip/Engine/Port - args.devAddr, // Dev Addr - args.offset_length, // Offset size - offset, // Offset - io_buflen, // Buffer length - io_buffer // Buffer - ); - } - else - { - TRACFCOMP(g_trac_i2c, - ERR_MRK"Hypervisor I2C read interface not linked"); - l_host_if_enabled = false; - } + rc = g_hostInterfaces->i2c_read + ( + proc_engine_port, // Master Chip/Engine/Port + args.devAddr, // Dev Addr + args.offset_length, // Offset size + offset, // Offset + io_buflen, // Buffer length + io_buffer // Buffer + ); } - else if (i_opType == DeviceFW::WRITE) + else { - if(g_hostInterfaces->i2c_write != NULL) - { - rc = g_hostInterfaces->i2c_write - ( - proc_engine_port, // Master Chip/Engine/Port - args.devAddr, // Dev Addr - args.offset_length, // Offset size - offset, // Offset - io_buflen, // Buffer length - io_buffer // Buffer - ); - } - else - { - TRACFCOMP(g_trac_i2c, - ERR_MRK"Hypervisor I2C write interface not linked"); - l_host_if_enabled = false; - } + TRACFCOMP(g_trac_i2c, + ERR_MRK"Hypervisor I2C read interface not linked"); + l_host_if_enabled = false; + } + } + else if (i_opType == DeviceFW::WRITE) + { + if(g_hostInterfaces->i2c_write != NULL) + { + rc = g_hostInterfaces->i2c_write + ( + proc_engine_port, // Master Chip/Engine/Port + args.devAddr, // Dev Addr + args.offset_length, // Offset size + offset, // Offset + io_buflen, // Buffer length + io_buffer // Buffer + ); + } + else + { + TRACFCOMP(g_trac_i2c, + ERR_MRK"Hypervisor I2C write interface not linked"); + l_host_if_enabled = false; } } diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index 35d51131c..3203f040d 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -15685,4 +15685,116 @@ firmware notes: Platforms should initialize this attribute to AUTO (0) + + WOF_ENABLED + + Defines if the Workload Optimization Frequency (WOF) system feature + where OCC algorithms will change (typically boost) the operational + frequency based on measured power available and any currently idling + cores. + + + + + non-volatile + + + ATTR_WOF_ENABLED + DIRECT + + + + + TRUSTED_SLAVE_SCAN_PATH_ACTIVE + + Set to indicate state of master->slave scan path. + Platform should default to false at beginning of IPL, and set to + true once trusted XSCOM path is active to all slave chips in drawer + + + + + volatile-zeroed + + + + ATTR_TRUSTED_SLAVE_SCAN_PATH_ACTIVE + DIRECT + + + + + FORCE_SKIP_SBE_MASTER_INTR_SERVICE + + Set to force skip of SBE interrupt service for master chip. + Default is to disable the use of the SBE interrupt service. + + + + 1 + + + volatile + + + + ATTR_FORCE_SKIP_SBE_MASTER_INTR_SERVICE + DIRECT + + + + + FORCE_USE_SBE_SLAVE_SCAN_SERVICE + + Set to force use of SBE scan service for slave chips. + Default is to enable the use of the SBE scan service + only for slave chips with security enabled. + + + + + volatile-zeroed + + + + ATTR_FORCE_USE_SBE_SLAVE_SCAN_SERVICE + DIRECT + + + + + SBE_MASTER_INTR_SERVICE_DELAY_CYCLES + + Cycle delay of SBE master interrupt service loop wait statement. + Paces rate of decrementer progress and prevents SBE from consuming PIB. + + + + + volatile-zeroed + + + + ATTR_SBE_MASTER_INTR_SERVICE_DELAY_CYCLES + DIRECT + + + + + SBE_MASTER_INTR_SERVICE_DELAY_US + + Execution delay (in microseconds) of SBE master interrupt service loop. + + + + + volatile-zeroed + + + + ATTR_SBE_MASTER_INTR_SERVICE_DELAY_US + DIRECT + + + diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 890a150aa..de3feb665 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -1366,4 +1366,21 @@ ID for the sensor number returned with the elog. --> + + SBE_MASTER_INTR_SERVICE_ENABLED + + Indicator whether the SBE interupt service is anabled. + 0=Not Enabled + 1=Enabled + + + + + + volatile-zeroed + + + + + diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index cf8810d6e..fae44c012 100644 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -301,6 +301,12 @@ BRAZOS_RX_FIFO_OVERRIDE HIDDEN_ERRLOGS_ENABLE MRW_NEST_CAPABLE_FREQUENCIES_SYS + WOF_ENABLED + TRUSTED_SLAVE_SCAN_PATH_ACTIVE + FORCE_SKIP_SBE_MASTER_INTR_SERVICE + FORCE_USE_SBE_SLAVE_SCAN_SERVICE + SBE_MASTER_INTR_SERVICE_DELAY_CYCLES + SBE_MASTER_INTR_SERVICE_DELAY_US diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index f5a40bbc5..2aa2b006a 100644 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -76,6 +76,7 @@ IPMI_SENSORS IPMI_MAX_BUFFER_SIZE OCC_COMMON_AREA_PHYS_ADDR + SBE_MASTER_INTR_SERVICE_ENABLED -- cgit v1.2.1