diff options
| author | Thi Tran <thi@us.ibm.com> | 2013-02-16 12:15:55 -0600 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-02-22 11:53:46 -0600 |
| commit | 5535a79cbab37d06d898076f9e2e87a40dc52ea7 (patch) | |
| tree | 7d6813764dc001db5a19b84f568f62d726b54051 /src | |
| parent | 60483517d931115eddf157b35fd7055df930cdfa (diff) | |
| download | talos-hostboot-5535a79cbab37d06d898076f9e2e87a40dc52ea7.tar.gz talos-hostboot-5535a79cbab37d06d898076f9e2e87a40dc52ea7.zip | |
TULETA PON - Winkle HW procedures update 02/16/2013
Change-Id: Ia7336fbe51e0293815dc47fe21cab360260a3f9a
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3220
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
19 files changed, 1766 insertions, 1185 deletions
diff --git a/src/usr/hwpf/hwp/build_winkle_images/makefile b/src/usr/hwpf/hwp/build_winkle_images/makefile index 5a7682500..2b87c1a5b 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/makefile +++ b/src/usr/hwpf/hwp/build_winkle_images/makefile @@ -75,7 +75,7 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar ## Point to the PORE image in PNOR ## taken from ref image ## /afs/awd.austin.ibm.com/projects/eclipz/lab/p8/gsiexe/compiled_pgm_sources/scratch_image/vpo/910520/s1.sbe_ref.bin -BINARY_FILES = $(IMGDIR)/procpore.dat:8886974065a94f3ea83d98be88716e063bcba57e +BINARY_FILES = $(IMGDIR)/procpore.dat:15def9e08f862467f910f6fa43b782ceffdf50b9 include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C index a879ffc18..0bf8aca9d 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,9 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pfet_init.C,v 1.1_Thi_hack 2012/12/07 20:12:27 stillgs Exp $ -// Search for @thi to see HACK of minor issues in order to compile -// RTC 60779 is opened to make sure a revised version is worked on by Greg Stills +// $Id: p8_pfet_init.C,v 1.2 2013/01/29 19:39:45 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pfet_init.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -32,7 +30,7 @@ // *! OWNER NAME: Greg Still Email: stillgs@us.ibm.com // *! /// \file p8_pfet_init.C -/// \brief Configure and initialize the EX PFET controllers based on +/// \brief Configure and initialize the EX PFET controllers based on /// attribute information and removes the override function. /// /// High-level procedure flow: @@ -41,9 +39,9 @@ /// Check for valid parameters /// if PM_CONFIG { /// Nop (all the work is done in PM_INIT as this procedure is not run -/// for the PM Reset path (eg, only done at IPL) +/// for the PM Reset path (eg, only done at IPL) /// else if PM_INIT { -/// Get the delay setting held in platform attributes +/// Get the delay setting held in platform attributes /// Convert these to hardware values /// for each EX chiplet { /// Store the Core VDD delay and VRET/VOFF values @@ -151,7 +149,7 @@ p8_pfet_init(const Target& i_target, uint32_t mode) /// ------------------------------- /// Unsupported Mode - else + else { FAPI_ERR("Unknown mode passed to p8_pfet_init. Mode %x ....", mode); @@ -176,9 +174,9 @@ pfet_init(const Target& i_target) uint8_t l_functional = 0; uint8_t l_ex_number = 0; bool error_flag = false; - + uint64_t address; - + uint8_t core_vret_voff_value; uint8_t eco_vret_voff_value; @@ -216,7 +214,7 @@ pfet_init(const Target& i_target) /// ATTR_PM_PFET_POWERUP_ECO_DELAY0 /// ATTR_PM_PFET_POWERUP_ECO_DELAY1 /// ATTR_PM_PFET_POWERDOWN_CORE_DELAY0 - /// ATTR_PM_PFET_POWERDOWN_CORE_DELAY1 + /// ATTR_PM_PFET_POWERDOWN_CORE_DELAY1 /// ATTR_PM_PFET_POWERDOWN_ECO_DELAY0 /// ATTR_PM_PFET_POWERDOWN_ECO_DELAY1 /// Output feature attributes @@ -237,11 +235,11 @@ pfet_init(const Target& i_target) { FAPI_INF("Executing pfet_config..."); - + // Harcoded defaults that don't come via attribute // Vret (not supported) = "off" (stage 0 = 0xB) for bits 0:3 // Voff = "off" (stage 01 = 0xB) for bits 4:7 - // \todo The scan0 values are zeros which indicate that the + // \todo The scan0 values are zeros which indicate that the // power won't go off. Double check the setting below!!! core_vret_voff_value = 0xBB; eco_vret_voff_value = 0xBB; @@ -263,7 +261,7 @@ pfet_init(const Target& i_target) /// ---------------------------------------------------------- l_rc = FAPI_ATTR_GET( ATTR_FREQ_PROC_REFCLOCK, - NULL, //@thi - wrong target &i_target, + NULL, attr_proc_refclk_frequency); if (l_rc) { @@ -271,7 +269,7 @@ pfet_init(const Target& i_target) FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } - + /// ---------------------------------------------------------- l_rc = FAPI_ATTR_GET( ATTR_PM_PFET_POWERUP_CORE_DELAY0, &i_target, @@ -424,9 +422,9 @@ pfet_init(const Target& i_target) attr_pm_pfet_powerdown_eco_delay1_value = convert_delay_to_value( attr_pm_pfet_powerdown_eco_delay1 , attr_proc_refclk_frequency); - + // Choosing always delay0 - attr_pm_pfet_powerup_core_sequence_delay_select = 0; + attr_pm_pfet_powerup_core_sequence_delay_select = 0; attr_pm_pfet_powerdown_core_sequence_delay_select = 0; attr_pm_pfet_powerup_eco_sequence_delay_select = 0; attr_pm_pfet_powerdown_eco_sequence_delay_select = 0; @@ -451,8 +449,8 @@ pfet_init(const Target& i_target) // Loop through all the functional chiplets // ****************************************************************** - l_rc = fapiGetChildChiplets(i_target, - TARGET_TYPE_EX_CHIPLET, + l_rc = fapiGetChildChiplets(i_target, + TARGET_TYPE_EX_CHIPLET, l_exChiplets, TARGET_STATE_PRESENT); if (l_rc) @@ -577,7 +575,7 @@ pfet_init(const Target& i_target) // ------------------------------------------------------------- FAPI_DBG("\tSetting ECO Voff Settings"); e_rc |= data.setBitLength(64); - e_rc |= data.insertFromRight(eco_vret_voff_value, 0, 8); + e_rc |= data.insertFromRight(eco_vret_voff_value, 0, 8); if (e_rc) { FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); @@ -652,12 +650,12 @@ pfet_set_delay( const fapi::Target& i_target, // convert_delay_to_value // Helper function to convert time values (binary in ns)to hardware delays //------------------------------------------------------------------------------ -uint8_t -convert_delay_to_value (uint32_t i_delay, +uint8_t +convert_delay_to_value (uint32_t i_delay, uint32_t i_attr_proc_nest_frequency) { uint8_t pfet_delay_value; - float dly; + float dly; // attr_proc_nest_frequency [MHz] // delay [ns] // pfet_delay_value = 15 - log2( i_delay * i_attr_proc_nest_frequency/1000); diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pm.H b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pm.H index ed6ac1b42..6999f9bf0 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pm.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pm.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pm.H,v 1.1 2012/08/23 04:58:58 stillgs Exp $ +// $Id: p8_pm.H,v 1.2 2012/12/07 20:20:10 stillgs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pm.H,v $ //------------------------------------------------------------------------------ // *| @@ -58,12 +58,13 @@ extern "C" { #ifndef _P8_PM_FLOW_MODE #define _P8_PM_FLOW_MODE enum p8_PM_FLOW_MODE { - PM_CONFIG = 0x1, - PM_RESET = 0x2, - PM_INIT = 0x3, - PM_SETUP = 0x4, - PM_SETUP_PIB = 0x5, - PM_SETUP_ALL = 0x6 + PM_CONFIG = 0x1, + PM_RESET = 0x2, + PM_INIT = 0x3, + PM_SETUP = 0x4, + PM_SETUP_PIB = 0x5, + PM_SETUP_ALL = 0x6, + PM_RESET_NOPMC = 0x7 }; #endif // _P8_PM_FLOW_MODE diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pmc_deconfig_setup.C b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pmc_deconfig_setup.C index 619ff0b08..72b9ef5c8 100755 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pmc_deconfig_setup.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pmc_deconfig_setup.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pmc_deconfig_setup.C,v 1.6 2012/09/28 15:24:33 stillgs Exp $ +// $Id: p8_pmc_deconfig_setup.C,v 1.7 2012/12/19 09:52:36 pchatnah Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pmc_deconfig_setup.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -148,10 +148,12 @@ p8_pmc_deconfig_setup(const Target& i_target) break; } + FAPI_INF(" Working on ex chiplet number %d", l_ex_number); + l_rc=fapiGetScom(i_target, (EX_GP3_0x100F0012+(l_ex_number*0x01000000)), data); if(l_rc) { - FAPI_ERR("GetScom error"); + FAPI_ERR("GetScom error "); break; } diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_poreslw_init.C b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_poreslw_init.C index 31230b01e..67f945a36 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_poreslw_init.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_poreslw_init.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,9 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_poreslw_init.C,v 1.8_Thi_hack 2012/12/12 04:25:54 stillgs Exp $ -// Search for @thi to see HACK of minor issues in order to compile -// RTC 60779 is opened to make sure a revised version is worked on by Greg +// $Id: p8_poreslw_init.C,v 1.9 2012/12/20 05:21:05 stillgs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_poreslw_init.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -68,10 +66,8 @@ #include "p8_pfet_init.H" #include "p8_pmc_deconfig_setup.H" -//#ifdef FAPIECMD -extern "C" { -//#endif +extern "C" { using namespace fapi; @@ -170,7 +166,7 @@ poreslw_init(const Target& i_target) break; } - FAPI_DBG("Activate the PMC Idle seequencer by making sure the Halt bit is clear"); // @thi - Hack + FAPI_DBG("Activate the PMC Idle seequencer by making sure the Halt bit is clear"); const uint32_t HALT_IDLE_STATE_MASTER_FSM = 14; l_rc = fapiGetScom(i_target, PMC_MODE_REG_0x00062000, data); if(!l_rc.ok()) @@ -193,8 +189,8 @@ poreslw_init(const Target& i_target) FAPI_ERR("Scom error writing PMC_MODE"); break; } - - FAPI_DBG("Activate the PMC Idle seequencer by making sure the Halt bit is clear"); // @thi - Hack + + FAPI_DBG("Activate the PMC Idle seequencer by making sure the Halt bit is clear"); // Setup up each of the EX chiplets l_rc = poreslw_ex_setup(i_target); @@ -352,7 +348,7 @@ poreslw_ex_setup(const Target& i_target) const uint32_t PM_WINKLE_POWER_UP_EN_BIT = 4; const uint32_t PM_WINKLE_POWER_OFF_SEL_BIT = 5; - // Warning: this need removal once mutli-core IPL function in SBE code is available + const uint32_t IDLE_STATE_OVERRIDE_EN = 6; const uint32_t PM_DISABLE = 0; @@ -614,7 +610,9 @@ poreslw_ex_setup(const Target& i_target) FAPI_INF("\tDisable the PCBS Heartbeat EX %x", l_ex_number); address = EX_SLAVE_CONFIG_0x100F001E + (l_ex_number * 0x01000000); - l_rc = fapiGetScom(l_exChiplets[j], EX_OHA_MODE_REG_RWx1002000D, data); +//@thi - Temporary workaround. Greg Still agreed to fix this in his next version +// l_rc = fapiGetScom(l_exChiplets[j], address, data); + l_rc = fapiGetScom(i_target, address, data); if(!l_rc.ok()) { FAPI_ERR("Scom error reading PCBS Slave Config"); @@ -636,77 +634,98 @@ poreslw_ex_setup(const Target& i_target) break; } - // >>>> Start: Move to SBE/SLW code with multi-core winkle function (proc_sbe_ex_scominit.S) // -------------------------------------- - // Clear the OHA Idle State Override - FAPI_INF("\tClear the OHA Idle State Override for EX %x", l_ex_number); - + // Check if SBE code has already cleard the OHA override. + // As chiplets may be enabled but offline (eg in Winkle) + // treat SCOM errors as off-line (eg skip it). If online + // and set, clear the override. l_rc = fapiGetScom(l_exChiplets[j], EX_OHA_MODE_REG_RWx1002000D, data); - if(!l_rc.ok()) - { - FAPI_ERR("Scom error reading OHA_MODE"); - break; - } - - e_rc |= data.clearBit(IDLE_STATE_OVERRIDE_EN); - if (e_rc) - { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); - l_rc.setEcmdError(e_rc); - break; + if(l_rc.ok()) + { + if (data.isBitSet(IDLE_STATE_OVERRIDE_EN)) + { + + FAPI_INF("\tClear the OHA Idle State Override for EX %x", l_ex_number); + e_rc |= data.clearBit(IDLE_STATE_OVERRIDE_EN); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc = fapiPutScom(l_exChiplets[j], EX_OHA_MODE_REG_RWx1002000D, data); + if(!l_rc.ok()) + { + FAPI_ERR("Scom error writing OHA_MODE"); + break; + } + } } - - l_rc = fapiPutScom(l_exChiplets[j], EX_OHA_MODE_REG_RWx1002000D, data); - if(!l_rc.ok()) - { - FAPI_ERR("Scom error writing OHA_MODE"); - break; - } - - // >>>> End: Move to SBE/SLW code with multi-core winkle function (proc_sbe_ex_scominit.S) - - // >>>> Start: Move to proc_sbe_ + // -------------------------------------- - // Activate the PCBS-PM macro by clearing the PM_DISABLE bit - FAPI_INF("\tActivate the PCBS-PM for EX %x", l_ex_number); - - e_rc |= data.flushTo1(); - e_rc |= data.clearBit(PM_DISABLE); - if (e_rc) + // Check that PM function is enabled (eg not disabled). + // If not, remove the disable + address = EX_PMGP0_0x100F0100 + (l_ex_number * 0x01000000); + l_rc=fapiGetScom(i_target, address, data); + if(!l_rc.ok()) { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); - l_rc.setEcmdError(e_rc); + FAPI_ERR("Scom error reading PMGP0"); break; } - - address = EX_PMGP0_AND_0x100F0101 + (l_ex_number * 0x01000000); - l_rc=fapiPutScom(i_target, address, data); - if(!l_rc.ok()) + + if (data.isBitSet(PM_DISABLE)) { - FAPI_ERR("Scom error writing EX_PMGP0_OR"); - break; + + // Activate the PCBS-PM macro by clearing the PM_DISABLE bit + FAPI_INF("\tActivate the PCBS-PM for EX %x", l_ex_number); + + e_rc |= data.flushTo1(); + e_rc |= data.clearBit(PM_DISABLE); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + address = EX_PMGP0_AND_0x100F0101 + (l_ex_number * 0x01000000); + l_rc=fapiPutScom(i_target, address, data); + if(!l_rc.ok()) + { + FAPI_ERR("Scom error writing EX_PMGP0_OR"); + break; + } } // -------------------------------------- // Clear OCC Special Wake-up bit - only 1 bit in the register - FAPI_INF("\tClear OCC Special Wake-up for EX %x", l_ex_number); - e_rc |= data.flushTo0(); - if (e_rc) - { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); - l_rc.setEcmdError(e_rc); - break; - } - address = EX_PMSpcWkupOCC_REG_0x100F010C + (l_ex_number * 0x01000000); - l_rc=fapiPutScom(i_target, address, data); + l_rc=fapiGetScom(i_target, address, data); if(!l_rc.ok()) { FAPI_ERR("Scom error clearing EX_OCC_SPWKUP"); break; } - // >>>> End: Move to proc_sbe_ - + + if (data.isBitSet(0)) + { + FAPI_INF("\tClear OCC Special Wake-up for EX %x", l_ex_number); + e_rc |= data.flushTo0(); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom(i_target, address, data); + if(!l_rc.ok()) + { + FAPI_ERR("Scom error clearing EX_OCC_SPWKUP"); + break; + } + } core_flag = true; } // Chiplet Enabled else // Not Functional so skip it diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_set_pore_bar.C b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_set_pore_bar.C index 38687022f..92d41cb7a 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_set_pore_bar.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_set_pore_bar.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ 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 fef7ac200..22792afcd 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 @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_delta_scan_rw.h,v 1.29 2013/01/02 03:03:10 cmolsen Exp $ +// $Id: p8_delta_scan_rw.h,v 1.35 2013/02/13 00:24:08 cmolsen 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 ~50MB image buffer size. @@ -33,11 +33,14 @@ /***** Xip customize support ****/ #define COMBINED_GOOD_VECTORS_TOC_NAME "combined_good_vectors" +#define L2_SINGLE_MEMBER_ENABLE_TOC_NAME "l2_single_member_enable_mask" #define PROC_PIB_REPR_VECTOR_TOC_NAME "proc_sbe_pibmem_repair_vector" #define NEST_SKEWADJUST_VECTOR_TOC_NAME "proc_sbe_nest_skewadjust_vector" #define MAX_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_CEN_PLL_RING_SIZE 80 // Bytes +#define TP_PLL_BNDY_RING_ALT_TOC_NAME "tp_pll_bndy_ring_alt" /***** Scan setting *****/ #define OPCG_SCAN_RATIO 4 @@ -82,10 +85,12 @@ #define IMGBUILD_ERR_CHECK_CODE 9 // Coding or image data problem. #define IMGBUILD_INVALID_IMAGE 10 // Invalid image. #define IMGBUILD_IMAGE_SIZE_MISMATCH 11 // Mismatch between image sizes. +#define IMGBUILD_IMAGE_SIZE_MESS 12 // Messed up image or section sizes. #define IMGBUILD_ERR_PORE_INLINE 20 // Pore inline error. #define IMGBUILD_ERR_PORE_INLINE_ASM 21 // Err assoc w/inline assembler. #define IMGBUILD_ERR_WF_CREATE 45 // Err assoc w/create_wiggle_flip_prg. #define IMGBUILD_ERR_RING_WRITE_TO_IMAGE 46 // Err assoc w/wr_ring_block_to_img. +#define IMGBUILD_ERR_SECTION_SIZING 48 // Err assoc w/section sizing. #define IMGBUILD_ERR_GET_SECTION 49 // Err assoc w/getting section ID. #define IMGBUILD_ERR_SECTION_DELETE 50 // Err assoc w/deleting ELF section. #define IMGBUILD_ERR_APPEND 51 // Err assoc w/appending to ELF section. @@ -125,9 +130,9 @@ #define MY_DBG(_fmt_, _args_...) FAPI_DBG(_fmt_, ##_args_) #else // End of __FAPI #ifdef SLW_COMMAND_LINE -#define MY_INF(_fmt_, _args_...) fprintf(stdout, _fmt_, ##_args_) -#define MY_ERR(_fmt_, _args_...) fprintf(stderr, _fmt_, ##_args_) -#define MY_DBG(_fmt_, _args_...) fprintf(stdout, _fmt_, ##_args_) +#define MY_INF(_fmt_, _args_...) printf(_fmt_, ##_args_) +#define MY_ERR(_fmt_, _args_...) printf(_fmt_, ##_args_) +#define MY_DBG(_fmt_, _args_...) printf(_fmt_, ##_args_) #else // End of SLW_COMMAND_LINE #define MY_INF(_fmt_, _args_...) #define MY_ERR(_fmt_, _args_...) @@ -165,7 +170,8 @@ #include <p8_image_help_base.H> -#ifndef SLW_COMMAND_LINE_RAM // We don't need this include for ramming. +#if !(defined __P8_PORE_TABLE_GEN_API_C) && !(defined __CEN_XIP_CUSTOMIZE_C) && !(defined SLW_COMMAND_LINE_RAM) +// We don't need this include for gen_cpureg/scom or slw ramming. #include <p8_scan_compression.H> #endif @@ -179,7 +185,7 @@ extern "C" { #endif -#ifndef SLW_COMMAND_LINE_RAM +#if !(defined __P8_PORE_TABLE_GEN_API_C) && !(defined SLW_COMMAND_LINE_RAM) // Info: // DeltaRingLayout describes the sequential order of the content in the compressed delta @@ -214,6 +220,41 @@ typedef struct { char data[]; } MetaData; +int calc_ring_delta_state( + const uint32_t *i_init, + const uint32_t *i_alter, + uint32_t *o_delta, + const uint32_t i_ringLen); + +int create_wiggle_flip_prg( + uint32_t *i_deltaRing, + uint32_t i_ringBitLen, + uint32_t i_scanSelectData, + uint32_t i_chipletID, + uint32_t **o_wfInline, + uint32_t *o_wfInlineLenInWords, +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + uint32_t i_scanMaxRotate, + uint32_t i_waitsScanDelay); +#else + uint32_t i_scanMaxRotate); +#endif + +uint64_t calc_ring_layout_entry_offset( + uint8_t i_typeRingLayout, + uint32_t i_sizeMetaData); + +int write_ring_block_to_image( + void *io_image, + const char *i_ringName, // NULL if no name. + DeltaRingLayout *i_ringBlock, + const uint8_t i_idxVector, // [0-15] - Ignored if ringName==NULL + const uint8_t i_override, // [0,1] - Ignored if ringName==NULL + const uint8_t i_overridable, // [0,1] - Ignored if ringName==NULL + const uint32_t i_sizeImageMax); + +#if !(defined __CEN_XIP_CUSTOMIZE_C) + int p8_centaur_build( void *i_imageIn, uint32_t i_ddLevel, @@ -233,15 +274,6 @@ int get_ring_layout_from_image2( DeltaRingLayout **o_rs4RingLayout, void **nextRing); -int write_ring_block_to_image( - void *io_image, - const char *i_ringName, // NULL if no name. - DeltaRingLayout *i_ringBlock, - const uint8_t i_idxVector, // [0-15] - Ignored if ringName==NULL - const uint8_t i_override, // [0,1] - Ignored if ringName==NULL - const uint8_t i_overridable, // [0,1] - Ignored if ringName==NULL - const uint32_t i_sizeImageMax); - int gen_ring_delta_state( uint32_t bitLen, uint32_t *i_init, @@ -249,12 +281,6 @@ int gen_ring_delta_state( uint32_t *o_delta, uint32_t verbose); -int calc_ring_delta_state( - const uint32_t *i_init, - const uint32_t *i_alter, - uint32_t *o_delta, - const uint32_t i_ringLen); - int write_rs4_ring_to_ref_image( char *i_fnImage, CompressedScanData *i_RS4, @@ -286,7 +312,8 @@ int write_vpd_ring_to_slw_image( uint8_t i_sysPhase, char *i_ringName, void *i_bufTmp, - uint32_t i_sizeBufTmp); + uint32_t i_sizeBufTmp, + uint8_t i_bWcSpace); int get_delta_ring_from_image( char *i_fnImage, @@ -312,32 +339,23 @@ int get_ring_layout_from_image( DeltaRingLayout *o_rs4RingLayout, void **nextRing); -int create_wiggle_flip_prg( - uint32_t *i_deltaRing, - uint32_t i_ringBitLen, - uint32_t i_scanSelectData, - uint32_t i_chipletID, - uint32_t **o_wfInline, - uint32_t *o_wfInlineLenInWords, - uint32_t i_scanMaxRotate); - int append_empty_section( void *io_image, - uint32_t *i_sizeImageMaxNew, + int *i_sizeImageMaxNew, uint32_t i_sectionId, - uint32_t i_sizeSection); + int *i_sizeSection, + uint8_t i_bFixed); int initialize_slw_section( void *io_image, uint32_t *i_sizeImageMaxNew); +int create_and_initialize_fixed_image( + void *io_image); + int update_runtime_scom_pointer( void *io_image); -uint64_t calc_ring_layout_entry_offset( - uint8_t i_typeRingLayout, - uint32_t i_sizeMetaData); - void cleanup( void *buf1=NULL, void *buf2=NULL, @@ -345,7 +363,9 @@ void cleanup( void *buf4=NULL, void *buf5=NULL); -#endif // End of not(SLW_COMMAND_LINE_RAM) +#endif // End of !(defined __CEN_XIP_CUSTOMIZE_C) + +#endif // End of !(defined __P8_PORE_TABLE_GEN_API_C) && !(defined SLW_COMMAND_LINE_RAM) // Byte-reverse a 32-bit integer if on an LE machine inline uint32_t myRev32(const uint32_t i_x) diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C index 0a5b21c7d..091f25d3e 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_image_help.C,v 1.35 2013/01/02 23:00:00 cmolsen Exp $ +// $Id: p8_image_help.C,v 1.48 2013/02/13 00:22:12 cmolsen Exp $ // /*------------------------------------------------------------------------------*/ /* *! TITLE : p8_image_help.C */ @@ -48,155 +48,66 @@ extern "C" { -// get_ring_layout_from_image() -// -int get_ring_layout_from_image( const void *i_imageIn, - uint32_t i_ddLevel, - uint8_t i_sysPhase, - DeltaRingLayout *o_rs4RingLayout, - void **nextRing) + +// calc_ring_delta_state() parms: +// i_init - init (flush) ring state +// i_alter - altered (desired) ring state +// o_delta - ring delta state, caller allocates buffer +// i_ringLen - length of ring in bits +int calc_ring_delta_state( const uint32_t *i_init, + const uint32_t *i_alter, + uint32_t *o_delta, + const uint32_t i_ringLen ) { - uint32_t rc=0, rcLoc=0; - uint8_t bRingFound=0, bRingEOS=0; - DeltaRingLayout *thisRingLayout, *nextRingLayout; //Pointers into memory mapped image. DO NOT CHANGE MEMBERS! - uint32_t sizeInitf; - SbeXipSection hostSection; - void *initfHostAddress0; - - SBE_XIP_ERROR_STRINGS(errorStrings); + int i=0, count=0, bit=0, remainder=0, remainingBits=0; + uint32_t init, alter; + uint32_t mask=0; - // Always first get the .initf stats from the TOC: - // - .initf host address offset and - // - .initf size - // - rc = sbe_xip_get_section( i_imageIn, SBE_XIP_SECTION_RINGS, &hostSection); - if (rc) { - MY_ERR("sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); - MY_ERR("Probable cause:"); - MY_ERR("\tThe section (=SBE_XIP_SECTION_RINGS=%i) was not found.",SBE_XIP_SECTION_RINGS); - return IMGBUILD_ERR_KEYWORD_NOT_FOUND; - } - if (hostSection.iv_offset==0) { - MY_INF("INFO : No ring data exists for the section ID = SBE_XIP_SECTION_RINGS (ID=%i).",SBE_XIP_SECTION_RINGS); - return DSLWB_RING_SEARCH_NO_MATCH; // Implies exhaust search as well. + // Do some checking of input parms + if ( (i_init==NULL) || (i_alter==NULL) || (o_delta==NULL) || (i_ringLen==0) ) { + MY_ERR("Bad input arguments.\n"); + return IMGBUILD_BAD_ARGS; } - initfHostAddress0 = (void*)((uintptr_t)i_imageIn + hostSection.iv_offset); - sizeInitf = hostSection.iv_size; - - // On first call, get the base offset to the .initf section. - // On subsequent calls, we're into the search for ddLevel and sysPhase, so use nextRing instead. - // - if (*nextRing==NULL) - nextRingLayout = (DeltaRingLayout*)initfHostAddress0; - else - nextRingLayout = (DeltaRingLayout*)*nextRing; - MY_DBG("initfHostAddress0 = 0x%016llx",(uint64_t)initfHostAddress0); - MY_DBG("sizeInitf = %i", sizeInitf); - MY_DBG("nextRingLayout = 0x%016llx",(uint64_t)nextRingLayout); - - // Populate the output RS4 ring BE layout structure as well as local structure in host LE format where needed. - // Note! Entire memory content is in BE format. So we do LE conversions where needed. - // - bRingFound = 0; - bRingEOS = 0; - - // SEARCH loop: Parse ring blocks successively until we find a ring that matches: - // ddLevel == i_ddLevel - // sysPhase == i_sysPhase - // - while (!bRingFound && !bRingEOS) { - thisRingLayout = nextRingLayout; - MY_DBG("Next backItemPtr = 0x%016llx",myRev64(thisRingLayout->backItemPtr)); - MY_DBG("Next ddLevel = 0x%02x",myRev32(thisRingLayout->ddLevel)); - MY_DBG("Next sysPhase = %i",thisRingLayout->sysPhase); - MY_DBG("Next override = %i",thisRingLayout->override); - MY_DBG("Next reserved1 = %i",thisRingLayout->reserved1); - MY_DBG("Next reserved2 = %i",thisRingLayout->reserved2); - - if (myRev32(thisRingLayout->ddLevel)==i_ddLevel) { // Is there a non-specific DD level, like for sys phase? - if ((thisRingLayout->sysPhase==0 && i_sysPhase==0) || - (thisRingLayout->sysPhase==1 && i_sysPhase==1) || - (thisRingLayout->sysPhase==2 && (i_sysPhase==0 || i_sysPhase==1))) { - bRingFound = 1; - MY_DBG("\tRing match found!"); - } - } - nextRingLayout = (DeltaRingLayout*)((uintptr_t)thisRingLayout + myRev32(thisRingLayout->sizeOfThis)); - *nextRing = (void*)nextRingLayout; - if (nextRingLayout>=(DeltaRingLayout*)((uintptr_t)initfHostAddress0+sizeInitf)) { - bRingEOS = 1; - *nextRing = NULL; - MY_DBG("\tRing search exhausted!"); - } - - } // End of SEARCH. + // Check how many 32-bit shift ops are needed and if we need final shift of remaining bit. + count = i_ringLen/32; + remainder = i_ringLen%32; + if (remainder>0) + count = count + 1; + remainingBits = i_ringLen; + MY_DBG("count=%i rem=%i remBits=%i\n",count,remainder,remainingBits); - if (bRingFound) { - if (bRingEOS) - rcLoc = DSLWB_RING_SEARCH_EXHAUST_MATCH; - else - rcLoc = DSLWB_RING_SEARCH_MATCH; - } - else { - *nextRing = NULL; - if (bRingEOS) - return DSLWB_RING_SEARCH_NO_MATCH; // Implies exhaust search as well. - else { - MY_ERR("Messed up ring search. Check code and .rings content. Returning nothing."); - return DSLWB_RING_SEARCH_MESS; - } - } + // XOR flush and init values 32 bits at a time. Store result in o_delta buffer. + for (i=0; i<count; i++) { - o_rs4RingLayout->entryOffset = thisRingLayout->entryOffset; - o_rs4RingLayout->backItemPtr = thisRingLayout->backItemPtr; - o_rs4RingLayout->sizeOfThis = thisRingLayout->sizeOfThis; - o_rs4RingLayout->sizeOfMeta = thisRingLayout->sizeOfMeta; - o_rs4RingLayout->ddLevel = thisRingLayout->ddLevel; - o_rs4RingLayout->sysPhase = thisRingLayout->sysPhase; - o_rs4RingLayout->override = thisRingLayout->override; - o_rs4RingLayout->reserved1 = thisRingLayout->reserved1; - o_rs4RingLayout->reserved2 = thisRingLayout->reserved2; - o_rs4RingLayout->metaData = (char*)(&thisRingLayout->reserved2 + - sizeof(thisRingLayout->reserved2)); - o_rs4RingLayout->rs4Launch = (uint32_t*)((uintptr_t)thisRingLayout + - myRev64(thisRingLayout->entryOffset)); - // entryOffset, rs4Launch and ASM_RS4_LAUNCH_BUF_SIZE should already be 8-byte aligned. - o_rs4RingLayout->rs4Delta = (uint32_t*)( (uintptr_t)thisRingLayout + - myRev64(thisRingLayout->entryOffset) + - ASM_RS4_LAUNCH_BUF_SIZE ); + if (remainingBits<=0) { + MY_ERR("remaingBits can not be negative.\n"); + return IMGBUILD_ERR_CHECK_CODE; + } - // Check that the ring layout structure in the memory is 8-byte aligned. This must - // be so because: - // - The entryOffset address must be on an 8-byte boundary because the start of the - // .rings section must be 8-byte aligned AND because the rs4Delta member is the - // last member and which must itself be 8-byte aligned. - // - These two things together means that both the beginning and end of the delta - // ring layout must be 8-byte aligned, and thus the whole block, i.e. sizeOfThis, - // must therefore automatically be 8-byte aligned. - // Also check that the RS4 delta ring is 8-byte aligned. - // Also check that the RS4 launcher is 8-byte aligned. - // - if (((uintptr_t)thisRingLayout-(uintptr_t)i_imageIn)%8 || - myRev32(o_rs4RingLayout->sizeOfThis)%8 || - myRev64(o_rs4RingLayout->entryOffset)%8 || - ASM_RS4_LAUNCH_BUF_SIZE%8) { - MY_ERR("Ring block or layout structure is not 8-byte aligned:"); - MY_ERR(" thisRingLayout-imageIn = %i",(uintptr_t)thisRingLayout-(uintptr_t)i_imageIn); - MY_ERR(" o_rs4RingLayout->sizeOfThis = %i",myRev32(o_rs4RingLayout->sizeOfThis)); - MY_ERR(" o_rs4RingLayout->entryOffset = %i",(uint32_t)myRev64(o_rs4RingLayout->entryOffset)); - MY_ERR(" ASM_RS4_LAUNCH_BUF_SIZE = %i",(uint32_t)ASM_RS4_LAUNCH_BUF_SIZE); - return IMGBUILD_ERR_MISALIGNED_RING_LAYOUT; - } + init = i_init[i]; + alter = i_alter[i]; - if (*nextRing > (void*)((uintptr_t)initfHostAddress0 + sizeInitf)) { - MY_INF("INFO : Book keeping got messed up during .initf search. Initf section does not appear aligned."); - MY_INF("initfHostAddress0+sizeInitf = 0x%016llx",(uint64_t)initfHostAddress0+sizeInitf); - MY_INF("nextRing = %i",*(uint32_t*)nextRing); - MY_INF("Continuing..."); - } + if (remainingBits>=32) + remainingBits = remainingBits-32; + else { //If remaining bits are less than 32 bits, mask unused bits + mask = 0; + for (bit=0; bit<(32-remainingBits); bit++) { + mask = mask << 1; + mask = mask + 1; + } + MY_DBG("remainingBits=%i<32. Padding w/zeros. True bit length unaltered. (@word count=%i)\n",remainingBits,count); + mask = ~mask; + init = init & mask; + alter = alter & mask; + remainingBits = 0; + } + + // Do the XORing. + o_delta[i] = init ^ alter; + } - return rcLoc; + return IMGBUILD_SUCCESS; } @@ -209,21 +120,28 @@ int get_ring_layout_from_image( const void *i_imageIn, int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta state (in BE format) uint32_t i_ringBitLen, // length of ring uint32_t i_scanSelectData, // Scan ring modifier data - uint32_t i_chipletID, // Chiplet ID - uint32_t **o_wfInline, // location of the PORE instructions data stream - uint32_t *o_wfInlineLenInWords, // final length of data stream - uint32_t i_scanMaxRotate) // Max rotate bit len on 38xxx + uint32_t i_chipletID, // Chiplet ID + uint32_t **o_wfInline, // location of the PORE instructions data stream + uint32_t *o_wfInlineLenInWords, // final length of data stream +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + uint32_t i_scanMaxRotate, // Max rotate bit len on 38xxx, or polling threshold on 39xxx. + uint32_t i_waitsScanDelay) // Temporary debug support. +#else + uint32_t i_scanMaxRotate) // Max rotate bit len on 38xxx, or polling threshold on 39xxx. +#endif { - uint32_t rc=0; //defined in p8_pore_api_const.h + uint32_t rc=0; uint32_t i=0; uint32_t scanSelectAddr=0; - uint32_t scanRing_baseAddr=0; + uint32_t scanRing_baseAddr=0, scanRing_baseAddr_long=0; uint32_t scanRing_poreAddr=0; uint32_t scanRingCheckWord=0; + uint32_t bitShift=0; uint32_t count=0; uint32_t rotateLen=0, remainder=0, remainingBits=0; + uint32_t clear_excess_dirty_bits_mask=0xffffffff; + uint32_t clean_up_shift_reg_mask=0xffffffff; uint64_t pore_imm64b=0; - //uint32_t maxWfInlineLenInWords = 3*MAX_RING_SIZE/32; uint32_t maxWfInlineLenInWords; PoreInlineContext ctx; @@ -231,17 +149,23 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s pore_inline_context_create(&ctx, *o_wfInline, maxWfInlineLenInWords * 4, 0, 0); - // Get chiplet and Ring Addr info. - // -------------------------------------------------------------------------- - + // // Set Default scanselq addr and scanring addr vars - scanSelectAddr=P8_PORE_CLOCK_CONTROLLER_REG; // 0x00030007: port 3 - clock cotrol endpt, x07- scanselq (regin & types) - // Descr: Addr of clock control SCOM reg. - scanRing_baseAddr=P8_PORE_SHIFT_REG; // 0x00038000: port 3, addr bit 16 must be set to 1 - // Also called GENERIC_CLK_SCANDATA0 - // Descr: SCOM reg for scan ring shifting. - scanRing_poreAddr=scanRing_baseAddr; // Init scan ring rotate addr - scanRingCheckWord=P8_SCAN_CHECK_WORD; // Header check word for checking ring write was successful + // + + // 0x00030007: port 3 - clock cotrol endpt, x07- scanselq (regin & types) + scanSelectAddr = P8_PORE_CLOCK_CONTROLLER_REG; + + // Addr of clock control SCOM register(s) for short and long rotates. + // + // Short: 0x00038000: port 3, addr bit 16 must be set to 1 and bit 19 to 0. + scanRing_baseAddr = P8_PORE_SHIFT_REG; + scanRing_poreAddr = scanRing_baseAddr; + // Long (poll): 0x00039000: port 3, addr bit 16 must be set to 1 and bit 19 to 1. + scanRing_baseAddr_long = P8_PORE_SHIFT_REG | 0x00001000; + + // Header check word for checking ring write was successful + scanRingCheckWord = P8_SCAN_CHECK_WORD; // This fix is a direct copy of the setp1_mcreadand macro in ./ipl/sbe/p8_slw.H uint64_t CLEAR_MC_TYPE_MASK=0x47; @@ -303,23 +227,6 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s return ctx.error; } -#ifdef IMGBUILD_PPD_WF_POLLING_PROT - // Setup On Product Clock Generator (OPCG) for polling. - pore_imm64b = uint64_t(0x01800000)<<32; - pore_STI(&ctx, P8_PORE_OPCG_CTRL_REG0_0x00030002, P0, pore_imm64b); - pore_imm64b = uint64_t(0x11480000)<<32 | uint64_t(0x00014800); - pore_STI(&ctx, P8_PORE_OPCG_CTRL_REG1_0x00030003, P0, pore_imm64b); - pore_imm64b = uint64_t(0x00000000)<<32 | uint64_t(0x0fff2800); - pore_STI(&ctx, P8_PORE_OPCG_CTRL_REG2_0x00030004, P0, pore_imm64b); - pore_imm64b = uint64_t(0x00000000); - pore_STI(&ctx, P8_PORE_OPCG_START_REG3_0x00030005, P0, pore_imm64b); - if (ctx.error > 0) { - MY_ERR("***POLLING PROT(1) rc = %d", ctx.error); - return ctx.error; - } -#endif - - #ifdef IMGBUILD_PPD_WF_WORST_CASE_PIB uint32_t poreCTR=0; // Save CTR value and restore it when done. @@ -335,14 +242,14 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s // Preload the scan data/shift reg with the scan header check word. // pore_imm64b = ((uint64_t)scanRingCheckWord) << 32; - pore_LI(&ctx, D0, pore_imm64b ); - if (ctx.error > 0) { - MY_ERR("***(1)LI D0 rc = %d", ctx.error); - return ctx.error; - } - pore_STD(&ctx, D0, scanRing_baseAddr, P0); +// pore_LI(&ctx, D0, pore_imm64b ); +// pore_STD(&ctx, D0, scanRing_baseAddr, P0); + pore_STI(&ctx, scanRing_baseAddr, P0, pore_imm64b); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + pore_WAITS(&ctx, i_waitsScanDelay); +#endif if (ctx.error > 0) { - MY_ERR("***STD D0 rc = %d", ctx.error); + MY_ERR("***STI(1) rc = %d", ctx.error); return ctx.error; } @@ -361,53 +268,47 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s MY_DBG("count=%i rem=%i remBits=%i",count,remainder,remainingBits); - // Compare 32 bit data at a time then shift ring (p7+ reqmt) - - // Read and compare init and flush values 32 bits at a time. Store delta in o_delta buffer. - //for (i=1; i<count; i++) { //Yong impl - for (i=0; i<count; i++) { //Mike impl + // Read and compare init and flush values 32 bits at a time. Store delta in + // o_delta buffer. + for (i=0; i<count; i++) { + if (i==(count-1)) { + // Cleanup any leftover bits in dirty buffer. (Only applies to last word.) + MY_DBG("Clearing any dirty bits in last WF word:\n"); + MY_DBG("i_deltaRing[%i] (before) = 0x%08x\n",i,i_deltaRing[i]); + MY_DBG("remainingBits = %i\n",remainingBits); + clear_excess_dirty_bits_mask = 0xffffffff>>(32-remainingBits); + i_deltaRing[i] = i_deltaRing[i]&clear_excess_dirty_bits_mask; + MY_DBG("clear_excess_dirty_bits_mask = 0x%08x\n",clear_excess_dirty_bits_mask); + MY_DBG("i_deltaRing[%i] (after) = 0x%08x\n",i,i_deltaRing[i]); + } + //==================================================================================== // If flush & init values are identical, increase the read count, no code needed. // When the discrepancy is found, read (rotate the ring) up to current address // then scan/write in the last 32 bits //==================================================================================== - // Note: For PORE scan instruction, set Port to 3. Bit 16 Must be set to 1. - if (i_deltaRing[i] > 0) { if (rotateLen > 0) { - //-------------------------------------------------------------------------- - // Rotate scan ring by the current rotate length - // rotate length is equivalent to current rotate addr - previous rotate addr - // - // Note space overflow is checked by inline assembler in P8 - // TODO: Not useing SCR1RDA : check with perv team - // TODO: what to do with 1st 32 bit for FSI?? - //-------------------------------------------------------------------------- #ifdef IMGBUILD_PPD_WF_POLLING_PROT uint32_t nwait1=0; PoreInlineLocation srcp1=0,tgtp1=0; - if (rotateLen>0x20) { - scanRing_poreAddr=scanRing_baseAddr | 0x20; - pore_LD(&ctx, D0, scanRing_poreAddr, P1); - rotateLen = rotateLen-0x20; - nwait1 = rotateLen * OPCG_SCAN_RATIO / 20 + 1; // 20x over sampling. - pore_STI(&ctx, P8_PORE_OPCG_CTRL_REG0_0x00030002, P0, - P8_OPCG_SCAN_RATIO_BITS|P8_OPCG_GO_BITS|uint64_t(rotateLen-1)); - PORE_LOCATION(&ctx, tgtp1); - pore_WAITS(&ctx, nwait1); - pore_LD(&ctx, D0, GENERIC_GP1_0x00000001, P1); - pore_ANDI(&ctx, D0, D0, P8_SCAN_POLL_MASK_BIT15); - PORE_LOCATION(&ctx, srcp1); - pore_BRAZ(&ctx, D0, tgtp1); - pore_inline_branch_fixup(&ctx, srcp1, tgtp1); - } - else { - scanRing_poreAddr=scanRing_baseAddr | rotateLen; - pore_LD(&ctx, D0, scanRing_poreAddr, P1); - } + + pore_imm64b = uint64_t(rotateLen)<<32; +// pore_LI(&ctx, D0, pore_imm64b); +// pore_STD(&ctx, D0, scanRing_baseAddr_long, P0); + pore_STI(&ctx, scanRing_baseAddr_long, P0, pore_imm64b); + + nwait1 = rotateLen / 20 + 1; // 20x over sampling. + PORE_LOCATION(&ctx, tgtp1); + pore_WAITS(&ctx, nwait1); + pore_LD(&ctx, D0, GENERIC_GP1_0x00000001, P1); + pore_ANDI(&ctx, D0, D0, P8_SCAN_POLL_MASK_BIT15); + PORE_LOCATION(&ctx, srcp1); + pore_BRAZ(&ctx, D0, tgtp1); + pore_inline_branch_fixup(&ctx, srcp1, tgtp1); if (ctx.error > 0) { MY_ERR("***POLLING PROT(2) rc = %d", ctx.error); return ctx.error; @@ -434,6 +335,9 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s #else scanRing_poreAddr = scanRing_baseAddr | rotateLen; pore_LD(&ctx, D0, scanRing_poreAddr, P1); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY +// pore_WAITS(&ctx, i_waitsScanDelay); +#endif if (ctx.error > 0) { MY_ERR("***LD D0 rc = %d", ctx.error); return ctx.error; @@ -443,33 +347,62 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s } // End of if (rotateLen>0) + // + // Shift in the delta state word, or parts of it if last word. + // if (remainingBits>32) - scanRing_poreAddr = scanRing_baseAddr | 32; + bitShift = 32; else - scanRing_poreAddr = scanRing_baseAddr | remainingBits; - - pore_imm64b = ((uint64_t)myRev32(i_deltaRing[i])) << 32; - - pore_LI(&ctx, D0, pore_imm64b ); - if (ctx.error > 0) { - MY_ERR("***(2)LI D0 rc = %d", ctx.error); - return ctx.error; + bitShift = remainingBits; + scanRing_poreAddr = scanRing_baseAddr | bitShift; + + if (i==(count-1) && bitShift<32) { + // -------------------------------------------------------------------- + // Be very careful shifting in last word content as it can mess up the + // current shift register content when loaded. + // -------------------------------------------------------------------- + // Take snapshot of present content of shift reg and put in D1. + pore_LD(&ctx, D1, scanRing_baseAddr, P1); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY +// pore_WAITS(&ctx, i_waitsScanDelay); +#endif + // Calculate shift reg cleanup mask and put in D0. The intent is to + // clear bit in the ring data positions while keeping any header + // check word content untouched. + clean_up_shift_reg_mask = 0xffffffff>>bitShift; + pore_imm64b = ((uint64_t)clean_up_shift_reg_mask) << 32; + pore_LI(&ctx, D0, pore_imm64b ); + // Cleanup shift register snapshot and put in D1. + pore_AND(&ctx, D1, D0, D1); + // Put ring data in D0. Note, any dirty content was removed earlier. + pore_imm64b = ((uint64_t)myRev32(i_deltaRing[i])) << 32; + pore_LI(&ctx, D0, pore_imm64b ); + // Finally, combine the ring data and the shift reg content and put in D0. + pore_OR(&ctx, D0, D0, D1); + pore_STD(&ctx, D0, scanRing_poreAddr, P0); } - - pore_STD(&ctx, D0, scanRing_poreAddr, P0); + else { + // -------------------------------------------------------------------- + // Not the last word OR the last word has exactly 32-bit of ring data. + // -------------------------------------------------------------------- + pore_imm64b = ((uint64_t)myRev32(i_deltaRing[i])) << 32; +// pore_LI(&ctx, D0, pore_imm64b ); + pore_STI(&ctx, scanRing_poreAddr, P0, pore_imm64b); + } + // Shift it in by bitShift bits. +// pore_STD(&ctx, D0, scanRing_poreAddr, P0); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + pore_WAITS(&ctx, i_waitsScanDelay); +#endif if (ctx.error > 0) { - MY_ERR("***STD D0 rc = %d", ctx.error); + MY_ERR("***STI(2) (or STD) rc = %d", ctx.error); return ctx.error; } rotateLen=0; //reset rotate length } - else { - // i_deltaRing[i]==0 (i.e., init and alter states are identical). - // Increase rotate length by remaining scan bits (32 by default). - - // Increase rotate length by remaining scan bits (default 32 bits) + else { // i_deltaRing[i]==0 (i.e., init and alter states are identical). if (remainingBits>32) rotateLen = rotateLen + 32; else @@ -478,45 +411,48 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s #ifdef IMGBUILD_PPD_WF_POLLING_PROT uint32_t nwait2=0; PoreInlineLocation srcp2=0,tgtp2=0; - // Max loop count is 16^7-1, so make sure we never exceed that. - if (rotateLen>=0xFFFFFE0) { - MY_DBG("/n/nScanning should never be here, should it?/n/n"); - scanRing_poreAddr=scanRing_baseAddr | 0x20; - pore_LD(&ctx, D0, scanRing_poreAddr, P1); - rotateLen = rotateLen-0x20; - nwait2 = rotateLen * OPCG_SCAN_RATIO / 20 + 1; // 20x over sampling. - pore_STI(&ctx, P8_PORE_OPCG_CTRL_REG0_0x00030002, P0, - P8_OPCG_SCAN_RATIO_BITS|P8_OPCG_GO_BITS|uint64_t(rotateLen-1)); - PORE_LOCATION(&ctx, tgtp2); - pore_WAITS(&ctx, nwait2); - pore_LD(&ctx, D0, GENERIC_GP1_0x00000001, P1); - pore_ANDI(&ctx, D0, D0, P8_SCAN_POLL_MASK_BIT15); - PORE_LOCATION(&ctx, srcp2); - pore_BRAZ(&ctx, D0, tgtp2); - pore_inline_branch_fixup(&ctx, srcp2, tgtp2); + + // Max rotate length is 2^20-1, i.e., data BITS(12-31)=>0x000FFFFF + if (rotateLen>=SCAN_MAX_ROTATE_LONG) { + MY_INF("Scanning should never be here since max possible ring length is\n"); + MY_INF("480,000 bits but MAX_LONG_ROTATE=0x%0x and rotateLen=0x%0x\n", + SCAN_MAX_ROTATE_LONG, rotateLen); + pore_imm64b = uint64_t(SCAN_MAX_ROTATE_LONG)<<32; +// pore_LI(&ctx, D0, pore_imm64b); +// pore_STD(&ctx, D0, scanRing_baseAddr_long, P0); + pore_STI(&ctx, scanRing_baseAddr_long, P0, pore_imm64b); + nwait2 = rotateLen / 20 + 1; // 20x over sampling. + PORE_LOCATION(&ctx, tgtp2); + pore_WAITS(&ctx, nwait2); + pore_LD(&ctx, D0, GENERIC_GP1_0x00000001, P1); + pore_ANDI(&ctx, D0, D0, P8_SCAN_POLL_MASK_BIT15); + PORE_LOCATION(&ctx, srcp2); + pore_BRAZ(&ctx, D0, tgtp2); + pore_inline_branch_fixup(&ctx, srcp2, tgtp2); if (ctx.error > 0) { MY_ERR("***POLLING PROT(3) rc = %d", ctx.error); return ctx.error; } - rotateLen=0; - } + rotateLen = rotateLen - SCAN_MAX_ROTATE_LONG; + } #else #ifdef IMGBUILD_PPD_WF_WORST_CASE_PIB // There is no max rotateLen issue in this case since we rotate 32 bits // at a time. #else - // PORE does not release PIB/PCB until CC acks, thus limiting bandwidth. - // It will time out if more than 4095 bits need to be rotated. - // If rotate length is more than 4032 (allows to rotate up to 4064 bits) - // rotate the chain and reset rotate length counter. - if (rotateLen>0xFC0) { - scanRing_poreAddr = scanRing_baseAddr | rotateLen; + if (rotateLen>i_scanMaxRotate) { + //scanRing_poreAddr = scanRing_baseAddr | rotateLen; + scanRing_poreAddr = scanRing_baseAddr | i_scanMaxRotate; pore_LD(&ctx, D0, scanRing_poreAddr, P1); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY +// pore_WAITS(&ctx, i_waitsScanDelay); +#endif if (ctx.error > 0) { MY_ERR("***LD D0 rc = %d", ctx.error); return ctx.error; } - rotateLen=0; + //rotateLen = 0; + rotateLen = rotateLen - i_scanMaxRotate; } #endif #endif @@ -531,30 +467,25 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s } // End of for loop // If the scan ring has not been rotated to the original position - // shift the ring by remaining shift bit length. (No need to do polling here.) + // shift the ring by remaining shift bit length. if (rotateLen>0) { #ifdef IMGBUILD_PPD_WF_POLLING_PROT uint32_t nwait3=0; PoreInlineLocation srcp3=0,tgtp3=0; - if (rotateLen>0x20) { - scanRing_poreAddr=scanRing_baseAddr | 0x20; - pore_LD(&ctx, D0, scanRing_poreAddr, P1); - rotateLen = rotateLen-0x20; - nwait3 = rotateLen * OPCG_SCAN_RATIO / 20 + 1; // 20x over sampling. - pore_STI(&ctx, P8_PORE_OPCG_CTRL_REG0_0x00030002, P0, - P8_OPCG_SCAN_RATIO_BITS|P8_OPCG_GO_BITS|uint64_t(rotateLen-1)); - PORE_LOCATION(&ctx, tgtp3); - pore_WAITS(&ctx, nwait3); - pore_LD(&ctx, D0, GENERIC_GP1_0x00000001, P1); - pore_ANDI(&ctx, D0, D0, P8_SCAN_POLL_MASK_BIT15); - PORE_LOCATION(&ctx, srcp3); - pore_BRAZ(&ctx, D0, tgtp3); - pore_inline_branch_fixup(&ctx, srcp3, tgtp3); - } - else { - scanRing_poreAddr=scanRing_baseAddr | rotateLen; - pore_LD(&ctx, D0, scanRing_poreAddr, P1); - } + + pore_imm64b = uint64_t(rotateLen)<<32; +// pore_LI(&ctx, D0, pore_imm64b); +// pore_STD(&ctx, D0, scanRing_baseAddr_long, P0); + pore_STI(&ctx, scanRing_baseAddr_long, P0, pore_imm64b); + + nwait3 = rotateLen / 20 + 1; // 20x over sampling. + PORE_LOCATION(&ctx, tgtp3); + pore_WAITS(&ctx, nwait3); + pore_LD(&ctx, D0, GENERIC_GP1_0x00000001, P1); + pore_ANDI(&ctx, D0, D0, P8_SCAN_POLL_MASK_BIT15); + PORE_LOCATION(&ctx, srcp3); + pore_BRAZ(&ctx, D0, tgtp3); + pore_inline_branch_fixup(&ctx, srcp3, tgtp3); if (ctx.error > 0) { MY_ERR("***POLLING PROT(4) rc = %d", ctx.error); return ctx.error; @@ -583,6 +514,9 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s #else scanRing_poreAddr=scanRing_baseAddr | rotateLen; pore_LD(&ctx, D0, scanRing_poreAddr, P1); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY +// pore_WAITS(&ctx, i_waitsScanDelay); +#endif if (ctx.error > 0) { MY_ERR("***LD D0 rc = %d", ctx.error); return ctx.error; @@ -633,25 +567,13 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s } // ...Load the output check word... pore_LD(&ctx, D0, scanRing_baseAddr, P1); +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY +// pore_WAITS(&ctx, i_waitsScanDelay); +#endif // Compare against the reference header check word... pore_XORI( &ctx, D0, D0, ((uint64_t)scanRingCheckWord) << 32); -#ifdef IMGBUILD_PPD_DEBUG_WF -pore_LI( &ctx, D1, ((uint64_t)scanRingCheckWord)<<32); -#endif PORE_LOCATION( &ctx, src5); pore_BRAZ( &ctx, D0, tgt5); -#ifdef IMGBUILD_PPD_DEBUG_WF -if (i_scanSelectData==0x00200800 || i_scanSelectData==0x04000800) { -pore_LD(&ctx, D1, scanRing_baseAddr, P1); -if (i_scanSelectData==0x00200800) { - pore_XORI( &ctx, D1, D1, ((uint64_t)0x00000001)<<32); // Yields B in last nibble. -} -if (i_scanSelectData==0x04000800) { - pore_XORI( &ctx, D1, D1, ((uint64_t)0x00000006)<<32); // Yields C in last nibble. -} -pore_RET( &ctx); -} -#endif pore_HALT( &ctx); PORE_LOCATION( &ctx, tgt5); if (ctx.error > 0) { @@ -684,27 +606,13 @@ pore_RET( &ctx); // ...Load the output check word... pore_LD(&ctx, D0, scanRing_baseAddr, P1); pore_XORI( &ctx, D0, D0, ((uint64_t)scanRingCheckWord) << 32); -#ifdef IMGBUILD_PPD_DEBUG_WF -pore_LI( &ctx, D1, ((uint64_t)scanRingCheckWord)<<32); -#endif PORE_LOCATION( &ctx, src8); pore_BRAZ( &ctx, D0, tgt8); -#ifdef IMGBUILD_PPD_DEBUG_WF -if (i_scanSelectData==0x00200800 || i_scanSelectData==0x04000800) { -pore_LD(&ctx, D1, scanRing_baseAddr, P1); -if (i_scanSelectData==0x00200800) { - pore_XORI( &ctx, D1, D1, ((uint64_t)0x00000001)<<32); // Yields B in last nibble. -} -if (i_scanSelectData==0x04000800) { - pore_XORI( &ctx, D1, D1, ((uint64_t)0x00000006)<<32); // Yields C in last nibble. -} -pore_RET( &ctx); -} -#endif pore_HALT( &ctx); PORE_LOCATION( &ctx, tgt8); - pore_LI( &ctx, D0, 0x0); // Do shadowing by setpulse. - pore_STD( &ctx, D0, GENERIC_CLK_SCAN_UPDATEDR_0x0003A000, P0); +// pore_LI( &ctx, D0, 0x0); // Do shadowing by setpulse. +// pore_STD( &ctx, D0, GENERIC_CLK_SCAN_UPDATEDR_0x0003A000, P0); + pore_STI(&ctx, GENERIC_CLK_SCAN_UPDATEDR_0x0003A000, P0, 0x0); pore_RET( &ctx); if (ctx.error > 0) { MY_ERR("***LD, XORI, BRANZ, RET or HALT went wrong rc = %d", ctx.error); @@ -733,6 +641,160 @@ pore_RET( &ctx); } +#if !(defined IMGBUILD_PPD_CEN_XIP_CUSTOMIZE) + +// get_ring_layout_from_image() +// +int get_ring_layout_from_image( const void *i_imageIn, + uint32_t i_ddLevel, + uint8_t i_sysPhase, + DeltaRingLayout *o_rs4RingLayout, + void **nextRing) +{ + uint32_t rc=0, rcLoc=0; + uint8_t bRingFound=0, bRingEOS=0; + DeltaRingLayout *thisRingLayout, *nextRingLayout; //Pointers into memory mapped image. DO NOT CHANGE MEMBERS! + uint32_t sizeInitf; + SbeXipSection hostSection; + void *initfHostAddress0; + + SBE_XIP_ERROR_STRINGS(errorStrings); + + // Always first get the .initf stats from the TOC: + // - .initf host address offset and + // - .initf size + // + rc = sbe_xip_get_section( i_imageIn, SBE_XIP_SECTION_RINGS, &hostSection); + if (rc) { + MY_ERR("sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe section (=SBE_XIP_SECTION_RINGS=%i) was not found.",SBE_XIP_SECTION_RINGS); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + if (hostSection.iv_offset==0) { + MY_INF("INFO : No ring data exists for the section ID = SBE_XIP_SECTION_RINGS (ID=%i).",SBE_XIP_SECTION_RINGS); + return DSLWB_RING_SEARCH_NO_MATCH; // Implies exhaust search as well. + } + initfHostAddress0 = (void*)((uintptr_t)i_imageIn + hostSection.iv_offset); + sizeInitf = hostSection.iv_size; + + // On first call, get the base offset to the .initf section. + // On subsequent calls, we're into the search for ddLevel and sysPhase, so use nextRing instead. + // + if (*nextRing==NULL) + nextRingLayout = (DeltaRingLayout*)initfHostAddress0; + else + nextRingLayout = (DeltaRingLayout*)*nextRing; + + MY_DBG("initfHostAddress0 = 0x%016llx",(uint64_t)initfHostAddress0); + MY_DBG("sizeInitf = %i", sizeInitf); + MY_DBG("nextRingLayout = 0x%016llx",(uint64_t)nextRingLayout); + + // Populate the output RS4 ring BE layout structure as well as local structure in host LE format where needed. + // Note! Entire memory content is in BE format. So we do LE conversions where needed. + // + bRingFound = 0; + bRingEOS = 0; + + // SEARCH loop: Parse ring blocks successively until we find a ring that matches: + // ddLevel == i_ddLevel + // sysPhase == i_sysPhase + // + while (!bRingFound && !bRingEOS) { + thisRingLayout = nextRingLayout; + MY_DBG("Next backItemPtr = 0x%016llx",myRev64(thisRingLayout->backItemPtr)); + MY_DBG("Next ddLevel = 0x%02x",myRev32(thisRingLayout->ddLevel)); + MY_DBG("Next sysPhase = %i",thisRingLayout->sysPhase); + MY_DBG("Next override = %i",thisRingLayout->override); + MY_DBG("Next reserved1 = %i",thisRingLayout->reserved1); + MY_DBG("Next reserved2 = %i",thisRingLayout->reserved2); + + if (myRev32(thisRingLayout->ddLevel)==i_ddLevel) { // Is there a non-specific DD level, like for sys phase? + if ((thisRingLayout->sysPhase==0 && i_sysPhase==0) || + (thisRingLayout->sysPhase==1 && i_sysPhase==1) || + (thisRingLayout->sysPhase==2 && (i_sysPhase==0 || i_sysPhase==1))) { + bRingFound = 1; + MY_DBG("\tRing match found!"); + } + } + nextRingLayout = (DeltaRingLayout*)((uintptr_t)thisRingLayout + myRev32(thisRingLayout->sizeOfThis)); + *nextRing = (void*)nextRingLayout; + if (nextRingLayout>=(DeltaRingLayout*)((uintptr_t)initfHostAddress0+sizeInitf)) { + bRingEOS = 1; + *nextRing = NULL; + MY_DBG("\tRing search exhausted!"); + } + + } // End of SEARCH. + + if (bRingFound) { + if (bRingEOS) + rcLoc = DSLWB_RING_SEARCH_EXHAUST_MATCH; + else + rcLoc = DSLWB_RING_SEARCH_MATCH; + } + else { + *nextRing = NULL; + if (bRingEOS) + return DSLWB_RING_SEARCH_NO_MATCH; // Implies exhaust search as well. + else { + MY_ERR("Messed up ring search. Check code and .rings content. Returning nothing."); + return DSLWB_RING_SEARCH_MESS; + } + } + + o_rs4RingLayout->entryOffset = thisRingLayout->entryOffset; + o_rs4RingLayout->backItemPtr = thisRingLayout->backItemPtr; + o_rs4RingLayout->sizeOfThis = thisRingLayout->sizeOfThis; + o_rs4RingLayout->sizeOfMeta = thisRingLayout->sizeOfMeta; + o_rs4RingLayout->ddLevel = thisRingLayout->ddLevel; + o_rs4RingLayout->sysPhase = thisRingLayout->sysPhase; + o_rs4RingLayout->override = thisRingLayout->override; + o_rs4RingLayout->reserved1 = thisRingLayout->reserved1; + o_rs4RingLayout->reserved2 = thisRingLayout->reserved2; + o_rs4RingLayout->metaData = (char*)(&thisRingLayout->reserved2 + + sizeof(thisRingLayout->reserved2)); + o_rs4RingLayout->rs4Launch = (uint32_t*)((uintptr_t)thisRingLayout + + myRev64(thisRingLayout->entryOffset)); + // entryOffset, rs4Launch and ASM_RS4_LAUNCH_BUF_SIZE should already be 8-byte aligned. + o_rs4RingLayout->rs4Delta = (uint32_t*)( (uintptr_t)thisRingLayout + + myRev64(thisRingLayout->entryOffset) + + ASM_RS4_LAUNCH_BUF_SIZE ); + + // Check that the ring layout structure in the memory is 8-byte aligned. This must + // be so because: + // - The entryOffset address must be on an 8-byte boundary because the start of the + // .rings section must be 8-byte aligned AND because the rs4Delta member is the + // last member and which must itself be 8-byte aligned. + // - These two things together means that both the beginning and end of the delta + // ring layout must be 8-byte aligned, and thus the whole block, i.e. sizeOfThis, + // must therefore automatically be 8-byte aligned. + // Also check that the RS4 delta ring is 8-byte aligned. + // Also check that the RS4 launcher is 8-byte aligned. + // + if (((uintptr_t)thisRingLayout-(uintptr_t)i_imageIn)%8 || + myRev32(o_rs4RingLayout->sizeOfThis)%8 || + myRev64(o_rs4RingLayout->entryOffset)%8 || + ASM_RS4_LAUNCH_BUF_SIZE%8) { + MY_ERR("Ring block or layout structure is not 8-byte aligned:"); + MY_ERR(" thisRingLayout-imageIn = %i",(uintptr_t)thisRingLayout-(uintptr_t)i_imageIn); + MY_ERR(" o_rs4RingLayout->sizeOfThis = %i",myRev32(o_rs4RingLayout->sizeOfThis)); + MY_ERR(" o_rs4RingLayout->entryOffset = %i",(uint32_t)myRev64(o_rs4RingLayout->entryOffset)); + MY_ERR(" ASM_RS4_LAUNCH_BUF_SIZE = %i",(uint32_t)ASM_RS4_LAUNCH_BUF_SIZE); + return IMGBUILD_ERR_MISALIGNED_RING_LAYOUT; + } + + if (*nextRing > (void*)((uintptr_t)initfHostAddress0 + sizeInitf)) { + MY_INF("INFO : Book keeping got messed up during .initf search. Initf section does not appear aligned."); + MY_INF("initfHostAddress0+sizeInitf = 0x%016llx",(uint64_t)initfHostAddress0+sizeInitf); + MY_INF("nextRing = %i",*(uint32_t*)nextRing); + MY_INF("Continuing..."); + } + + return rcLoc; +} + + // write_wiggle_flip_to_image() int write_wiggle_flip_to_image( void *io_imageOut, @@ -925,20 +987,22 @@ int write_wiggle_flip_to_image( void *io_imageOut, // append_empty_section() int append_empty_section( void *io_image, - uint32_t *i_sizeImageMaxNew, + int *i_sizeImageMaxNew, uint32_t i_sectionId, - uint32_t i_sizeSection) + int *i_sizeSection, + uint8_t i_bFixed) { - uint32_t rc=0; - uint32_t sizeImageIn=0, sizeImageOutThis=0, sizeImageOutThisEst=0; + int rc=0; + uint32_t sizeImageIn=0, sizeImageOutThis=0; + int sizeImageOutThisEst=0; uint32_t offsetCheck=1; - void *bufEmpty=NULL; + SbeXipSection xipSection; SBE_XIP_ERROR_STRINGS(errorStrings); rc = 0; - if (i_sizeSection==0) { + if (*i_sizeSection==0) { MY_INF("INFO : Requested append size = 0. Nothing to do."); return rc; } @@ -947,7 +1011,10 @@ int append_empty_section( void *io_image, // sbe_xip_image_size( io_image, &sizeImageIn); // ...estimate max size of new image - sizeImageOutThisEst = sizeImageIn + i_sizeSection + SBE_XIP_MAX_SECTION_ALIGNMENT; + if (i_bFixed) + sizeImageOutThisEst = sizeImageIn + *i_sizeSection; + else + sizeImageOutThisEst = sizeImageIn + *i_sizeSection + SBE_XIP_MAX_SECTION_ALIGNMENT; if (sizeImageOutThisEst>*i_sizeImageMaxNew) { MY_ERR("Estimated new image size (=%i) would exceed max allowed size (=%i).", sizeImageOutThisEst, *i_sizeImageMaxNew); @@ -955,36 +1022,34 @@ int append_empty_section( void *io_image, return IMGBUILD_ERR_IMAGE_TOO_LARGE; } - // Add the 0-initialized buffer as a section append. + // Add the NULL buffer as a section append. sbe_xip_append() initializes with 0s. // - bufEmpty = calloc( i_sizeSection, 1); rc = sbe_xip_append( io_image, i_sectionId, - bufEmpty, - i_sizeSection, + NULL, + *i_sizeSection, sizeImageOutThisEst, &offsetCheck); if (rc) { MY_ERR("xip_append() failed: %s\n",SBE_XIP_ERROR_STRING(errorStrings, rc)); - if (bufEmpty) - free(bufEmpty); return DSLWB_SLWB_IMAGE_ERROR; } if (offsetCheck) MY_INF("INFO : Section was not empty at time of xip_append(). It contained %i bytes.",offsetCheck); // ...get new image size, update return size, and test if successful update. sbe_xip_image_size( io_image, &sizeImageOutThis); - MY_DBG("Output image size (final)\t=%i",sizeImageOutThis); + MY_DBG("Output image size (after section append) = %i\n",sizeImageOutThis); *i_sizeImageMaxNew = sizeImageOutThis; rc = sbe_xip_validate( io_image, sizeImageOutThis); if (rc) { MY_ERR("xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); - if (bufEmpty) free(bufEmpty); return IMGBUILD_ERR_XIP_MISC; } - - if (bufEmpty) - free(bufEmpty); + + // Return final section size. + // + rc = sbe_xip_get_section( io_image, i_sectionId, &xipSection); + *i_sizeSection = xipSection.iv_size; return rc; } @@ -1002,6 +1067,7 @@ int initialize_slw_section( void *io_image, PoreInlineContext ctx; SbeXipSection xipSection; SbeXipItem xipTocItem; + int sizeSectionChk=0; void *hostScomTableNext, *hostScomVectorNext; void *hostScomVectorFirstNC, *hostScomVectorFirstL2, *hostScomVectorFirstL3; void *hostScomTableNC, *hostScomTableL2, *hostScomTableL3; @@ -1010,12 +1076,19 @@ int initialize_slw_section( void *io_image, SBE_XIP_ERROR_STRINGS(errorStrings); + sizeSectionChk = FIXED_SLW_SECTION_SIZE; rc = append_empty_section( io_image, - i_sizeImageMaxNew, + (int*)i_sizeImageMaxNew, SBE_XIP_SECTION_SLW, - SLW_RAM_TABLE_SIZE + SLW_SCOM_TABLE_SIZE_ALL); + &sizeSectionChk, + 0); if (rc) return rc; + if (sizeSectionChk!=FIXED_SLW_SECTION_SIZE) { + MY_ERR("Section size of .slw (=%i) not equal to requested size (=%i).\n", + sizeSectionChk, FIXED_SLW_SECTION_SIZE); + return IMGBUILD_ERR_SECTION_SIZING; + } // // Ramming table: Nothing to do. Already 0-initialized in append_empty_section(). @@ -1116,6 +1189,237 @@ int initialize_slw_section( void *io_image, +// create_and_initialize_fixed_image() +// - swell image to fixed size of 1MB by: +// - appending elastic section .fit +// - appending fixed section .slw +// - allocate space for Ramming and Scomming +// - appending fixed section .ffdc +// - populate Scomming table with ret/nop/nop/nop (RNNN) inline asm instructions +// - update Scomming vector +int create_and_initialize_fixed_image( void *io_image) +{ + int rc=0; + uint32_t i_coreId=0, i_iis=0; + uint32_t sizeImageIn=0; + int sizeImageChk=0; + int sizeSectionFit=0, sizeSectionReq=0, sizeSectionChk=0; + PoreInlineContext ctx; + SbeXipSection xipSection; + SbeXipItem xipTocItem; + void *hostRamVectorFirst, *hostRamVectorNext, *hostRamTable; + void *hostScomVectorFirstNC, *hostScomVectorFirstL2, *hostScomVectorFirstL3; + void *hostScomVectorNext; + void *hostScomTableNC, *hostScomTableL2, *hostScomTableL3; + void *hostScomTableNext; + uint64_t xipRamTable, xipScomTableNC, xipScomTableL2, xipScomTableL3; + uint8_t bufRNNN[XIPSIZE_SCOM_ENTRY]; + + SBE_XIP_ERROR_STRINGS(errorStrings); + + sbe_xip_image_size( io_image, &sizeImageIn); + + // Ensure, to play it safe, that last two sections (.slw & .ffdc) are both on + // 128-byte boundaries. The max [fixed] image size must itself already be + // 128-byte aligned. + sizeSectionFit = (int) ( FIXED_SLW_IMAGE_SIZE - + sizeImageIn - + FIXED_SLW_SECTION_SIZE - + FIXED_FFDC_SECTION_SIZE ); + if (sizeSectionFit<0) { + MY_ERR("Size of .fit section (=%i) can not be negative.\n",sizeSectionFit); + MY_ERR("Size of fixed image = %i\n",FIXED_SLW_IMAGE_SIZE); + MY_ERR("Size of input image = %i\n",sizeImageIn); + MY_ERR("Size of .slw section = %i\n",FIXED_SLW_SECTION_SIZE); + MY_ERR("Size of .ffdc section = %i\n",FIXED_FFDC_SECTION_SIZE); + return IMGBUILD_ERR_SECTION_SIZING; + } + + // Append .fit + // + sizeImageChk = FIXED_SLW_IMAGE_SIZE; + sizeSectionReq = sizeSectionFit; + sizeSectionChk = sizeSectionReq; + MY_INF("Appending .fit w/size=%i\n",sizeSectionReq); + rc = append_empty_section( io_image, + &sizeImageChk, + SBE_XIP_SECTION_FIT, + &sizeSectionChk, + 1); + if (rc) + return rc; + if (sizeSectionChk!=sizeSectionReq) { + MY_ERR("Section size of .fit (=%i) not equal to requested size (=%i).\n", + sizeSectionChk, sizeSectionReq); + return IMGBUILD_ERR_SECTION_SIZING; + } + + // Append .slw + // + sizeImageChk = FIXED_SLW_IMAGE_SIZE; + sizeSectionReq = FIXED_SLW_SECTION_SIZE; + sizeSectionChk = sizeSectionReq; + MY_INF("Appending .slw w/size=%i\n",sizeSectionReq); + rc = append_empty_section( io_image, + &sizeImageChk, + SBE_XIP_SECTION_SLW, + &sizeSectionChk, + 1); + if (rc) + return rc; + if (sizeSectionChk!=sizeSectionReq) { + MY_INF("Section size of .slw (=%i) not equal to requested size (=%i).\n", + sizeSectionChk, sizeSectionReq); + return IMGBUILD_ERR_SECTION_SIZING; + } + + + // Append .ffdc + // + sizeImageChk = FIXED_SLW_IMAGE_SIZE; + sizeSectionReq = FIXED_FFDC_SECTION_SIZE; + sizeSectionChk = sizeSectionReq; + MY_ERR("Appending .ffdc w/size=%i\n",sizeSectionReq); + rc = append_empty_section( io_image, + &sizeImageChk, + SBE_XIP_SECTION_FFDC, + &sizeSectionChk, + 1); + if (rc) + return rc; + if (sizeSectionChk!=sizeSectionReq) { + MY_ERR("Section size of .ffdc (=%i) not equal to requested size (=%i).\n", + sizeSectionChk, sizeSectionReq); + return IMGBUILD_ERR_SECTION_SIZING; + } + + // -------------------------------------------------------------------------- + // Ramming table: Already 0-initialized in append_empty_section(). + // -------------------------------------------------------------------------- + + // ... calc host ptr to Ram table in .slw section. + rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection); + if (rc) { + MY_ERR("sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe section (=SBE_XIP_SECTION_SLW=%i) was not found.",SBE_XIP_SECTION_SLW); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + hostRamTable = (void*)((uintptr_t)io_image + xipSection.iv_offset); + + // ... get location of Ram vector. + rc = sbe_xip_find( io_image, SLW_HOST_REG_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_REG_VECTOR_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostRamVectorFirst); + + // ... update Ram vector. + sbe_xip_host2pore( io_image, hostRamTable, &xipRamTable); + for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { + hostRamVectorNext = (void*)( (uint64_t*)hostRamVectorFirst + i_coreId); + *(uint64_t*)hostRamVectorNext = myRev64( xipRamTable + + SLW_RAM_TABLE_SPACE_PER_CORE*i_coreId); + } + + // -------------------------------------------------------------------------- + // Scomming table: Fill with RNNN (16-byte) instruction sequences. + // -------------------------------------------------------------------------- + + // ... create RNNN instruction sequence. + pore_inline_context_create( &ctx, (void*)bufRNNN, XIPSIZE_SCOM_ENTRY, 0, 0); + pore_RET( &ctx); + pore_NOP( &ctx); + pore_NOP( &ctx); + pore_NOP( &ctx); + if (ctx.error > 0) { + MY_ERR("***_RET or _NOP generated rc = %d", ctx.error); + return IMGBUILD_ERR_PORE_INLINE_ASM; + } + + // ... calc host ptr to Scom NC subsection. + // Note that we will assume, further down, that the NC section goes first, + // then the L2 section and then the L3 section. + rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection); + if (rc) { + MY_ERR("sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe section (=SBE_XIP_SECTION_SLW=%i) was not found.",SBE_XIP_SECTION_SLW); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + hostScomTableNC = (void*)((uintptr_t)io_image + xipSection.iv_offset + SLW_RAM_TABLE_SIZE); + + // ... populate entire Scom table with RNNN IIS, incl NC, L2 and L3 sections. + for (i_iis=0; i_iis<SLW_SCOM_TABLE_SIZE_ALL; i_iis=i_iis+XIPSIZE_SCOM_ENTRY) { + hostScomTableNext = (void*)( (uintptr_t)hostScomTableNC + i_iis); + memcpy( hostScomTableNext, (void*)bufRNNN, XIPSIZE_SCOM_ENTRY); + } + + hostScomTableL2 = (void*)((uintptr_t)hostScomTableNC + SLW_SCOM_TABLE_SIZE_NC); + hostScomTableL3 = (void*)((uintptr_t)hostScomTableL2 + SLW_SCOM_TABLE_SIZE_L2); + + // ... get location of ----> Scom NC <---- vector from TOC. + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_NC_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_NC_VECTOR_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirstNC); + + // ... update Scom NC vector. + sbe_xip_host2pore( io_image, hostScomTableNC, &xipScomTableNC); + for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { + hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirstNC + i_coreId); + *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableNC + + SLW_SCOM_TABLE_SPACE_PER_CORE_NC*i_coreId); + } + + // ... get location of ----> Scom L2 <---- vector from TOC. + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L2_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_L2_VECTOR_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirstL2); + + // ... update Scom L2 vector. + sbe_xip_host2pore( io_image, hostScomTableL2, &xipScomTableL2); + for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { + hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirstL2 + i_coreId); + *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableL2 + + SLW_SCOM_TABLE_SPACE_PER_CORE_L2*i_coreId); + } + + // ... get location of ----> Scom L3 <---- vector from TOC. + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L3_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_L3_VECTOR_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirstL3); + + // ... update Scom L3 vector. + sbe_xip_host2pore( io_image, hostScomTableL3, &xipScomTableL3); + for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { + hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirstL3 + i_coreId); + *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableL3 + + SLW_SCOM_TABLE_SPACE_PER_CORE_L3*i_coreId); + } + + return rc; +} + + + // update_runtime_scom_pointer() // - reprogram host_runtime_scom data to point to sub_slw_runtime_scom // - reprogram ex_enable_runtime_scom data to point to sub_slw_ex_enable_runtime_scom @@ -1123,7 +1427,7 @@ int update_runtime_scom_pointer( void *io_image) { int rc=0; uint64_t xipSlwRuntimeAddr; - uint64_t xipSlwExEnableRuntimeAddr; +// uint64_t xipSlwExEnableRuntimeAddr; SBE_XIP_ERROR_STRINGS(errorStrings); @@ -1147,7 +1451,8 @@ int update_runtime_scom_pointer( void *io_image) return IMGBUILD_ERR_KEYWORD_NOT_FOUND; } - // Get address of sub_slw_ex_enable_runtime_scom subroutine. +/* + // Get address of sub_slw_ex_enable_runtime_scom subroutine. // rc = sbe_xip_get_scalar( io_image, SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME, &xipSlwExEnableRuntimeAddr); if (rc) { @@ -1168,6 +1473,7 @@ int update_runtime_scom_pointer( void *io_image) return IMGBUILD_ERR_KEYWORD_NOT_FOUND; } } +*/ return 0; } @@ -1358,7 +1664,8 @@ int write_vpd_ring_to_slw_image(void *io_image, uint8_t i_sysPhase, char *i_ringName, void *i_bufTmp, // HB buf2 - uint32_t i_sizeBufTmp) + uint32_t i_sizeBufTmp, + uint8_t i_bWcSpace) { uint32_t rc=0, bufLC; uint8_t chipletId, idxVector=0; @@ -1415,6 +1722,18 @@ int write_vpd_ring_to_slw_image(void *io_image, MY_INF("scanMaxRotate set to 0x%llx; ", scanMaxRotate); MY_INF("Continuing...; "); } + +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + uint64_t waitsScanDelay=10; + // Temporary support for enforcing delay after scan WF scoms. + // Also remove all references and usages of waitsScanDelay in this file. + rc = sbe_xip_get_scalar( io_image, "waits_delay_for_scan", &waitsScanDelay); + if (rc) { + MY_ERR("Error obtaining waits_delay_for_scan keyword.\n"); + return IMGBUILD_ERR_XIP_MISC; + } +#endif + wfInline = (uint32_t*)i_bufRs4Ring; // Reuse this buffer (HB buf1) for wiggle-flip prg. wfInlineLenInWords = i_sizeBufTmp/4; // Assuming same size of both HB buf1 and buf2. rc = create_wiggle_flip_prg((uint32_t*)i_bufTmp, @@ -1423,7 +1742,12 @@ int write_vpd_ring_to_slw_image(void *io_image, (uint32_t)i_bufRs4Ring->iv_chipletId, &wfInline, &wfInlineLenInWords, // Is 8-byte aligned on return. +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + (uint32_t)scanMaxRotate, + (uint32_t)waitsScanDelay); +#else (uint32_t)scanMaxRotate); +#endif if (rc) { MY_ERR("create_wiggle_flip_prg() failed w/rc=%i; ",rc); return IMGBUILD_ERR_WF_CREATE; @@ -1441,8 +1765,23 @@ int write_vpd_ring_to_slw_image(void *io_image, entryOffsetWfRingBlock = calc_ring_layout_entry_offset( 1, 0); bufWfRingBlock->entryOffset = myRev64(entryOffsetWfRingBlock); bufWfRingBlock->backItemPtr = 0; // Will be updated below, as we don't know yet. - sizeWfRingBlock = entryOffsetWfRingBlock + // Must be 8-byte aligned. - wfInlineLenInWords*4; // Must be 8-byte aligned. + + // Allocate either fitted or worst-case space for the ring. For example, the + // rings, ex_repr_core/eco, need worst-case space allocation. + if (i_bWcSpace==0) { + // Fitted space sizing. + sizeWfRingBlock = entryOffsetWfRingBlock + // Must be 8-byte aligned. + wfInlineLenInWords*4; // Must be 8-byte aligned. + } + else { + // Worst-case space sizing. + sizeWfRingBlock = ((sizeRingRaw-1)/32 + 1) * 4 * WF_WORST_CASE_SIZE_FAC + + WF_ENCAP_SIZE; + sizeWfRingBlock = (uint32_t)myByteAlign(8, sizeWfRingBlock); + memset((void*)((uint64_t)bufWfRingBlock+entryOffsetWfRingBlock), + 0, + sizeWfRingBlock-entryOffsetWfRingBlock); + } // Quick check to see if final ring block size will fit in HB buffer. if (sizeWfRingBlock>sizeWfRingBlockMax) { MY_ERR("WF ring block size (=%i) exceeds HB buf2 size (=%i).", @@ -1491,68 +1830,17 @@ int write_vpd_ring_to_slw_image(void *io_image, } -// calc_ring_delta_state() parms: -// i_init - init (flush) ring state -// i_alter - altered (desired) ring state -// o_delta - ring delta state, caller allocates buffer -// i_ringLen - length of ring in bits -int calc_ring_delta_state( const uint32_t *i_init, - const uint32_t *i_alter, - uint32_t *o_delta, - const uint32_t i_ringLen ) -{ - int i=0, count=0, bit=0, remainder=0, remainingBits=0; - uint32_t init, alter; - uint32_t mask=0; - - // Do some checking of input parms - if ( (i_init==NULL) || (i_alter==NULL) || (o_delta==NULL) || (i_ringLen==0) ) { - MY_ERR("Bad input arguments.\n"); - return IMGBUILD_BAD_ARGS; - } - - // Check how many 32-bit shift ops are needed and if we need final shift of remaining bit. - count = i_ringLen/32; - remainder = i_ringLen%32; - if (remainder>0) - count = count + 1; - remainingBits = i_ringLen; - MY_DBG("count=%i rem=%i remBits=%i\n",count,remainder,remainingBits); - - // XOR flush and init values 32 bits at a time. Store result in o_delta buffer. - for (i=0; i<count; i++) { - - if (remainingBits<=0) { - MY_ERR("remaingBits can not be negative.\n"); - return IMGBUILD_ERR_CHECK_CODE; - } - - init = i_init[i]; - alter = i_alter[i]; - - if (remainingBits>=32) - remainingBits = remainingBits-32; - else { //If remaining bits are less than 32 bits, mask unused bits - mask = 0; - for (bit=0; bit<(32-remainingBits); bit++) { - mask = mask << 1; - mask = mask + 1; - } - MY_DBG("remainingBits=%i<32. Padding w/zeros. True bit length unaltered. (@word count=%i)\n",remainingBits,count); - mask = ~mask; - init = init & mask; - alter = alter & mask; - remainingBits = 0; - } - - // Do the XORing. - o_delta[i] = init ^ alter; - } - - return IMGBUILD_SUCCESS; -} - - +// CMO-20130208: Not used in: +// - p8_image_help.C +// - p8_image_help_base.C +// - cen_xip_customize.C +// - p8_pore_table_gen_api.C +// - p8_slw_repair.C +// - ??? +// It is used in: +// - p8_delta_scan_w +// - p8_delta_scan_r +// - ??? void cleanup( void *buf1, void *buf2, void *buf3, @@ -1566,5 +1854,6 @@ void cleanup( void *buf1, if (buf5) free(buf5); } +#endif // End of !(defined IMGBUILD_PPD_CEN_XIP_CUSTOMIZE) } diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H index 2829e2270..e85bec40a 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_image_help_base.H,v 1.9 2012/12/18 05:24:00 cmolsen Exp $ +// $Id: p8_image_help_base.H,v 1.12 2013/02/12 21:02:38 cmolsen Exp $ //------------------------------------------------------------------------------ // Title: p8_image_help_base.H // Description: Contains the most basic structures and defines needed for @@ -28,22 +28,32 @@ //------------------------------------------------------------------------------ const uint32_t MAX_REF_IMAGE_SIZE = 5000000; // Max reference image size. -const uint32_t FIXED_SLW_IMAGE_SIZE = 1000000; // Fixed SLW image size assumed by HB, PHYP and slw_build(). +// Fixed SLW image size (Ensure 128-byte alignment.) +const uint32_t FIXED_SLW_IMAGE_SIZE = 1024*1024; // Fixed SLW image size assumed by HB, PHYP and slw_build(). const uint32_t FIXED_RING_BUF_SIZE = 60000; // Fixed ring buffer size assumed by HB, PHYP and slw_build(). Only use when emulating FAPI calls and for command-line utilities. -const uint8_t MAX_VPD_TYPES = 2; // #G and #R, so far. -const uint8_t CHIPLET_ID_MIN = 0x00; -const uint8_t CHIPLET_ID_MAX = 0x1F; +const uint8_t MAX_VPD_TYPES = 2; // #G and #R, so far. +#define CHIPLET_ID_MIN 0x00 +#define CHIPLET_ID_MAX 0x1F const uint8_t MAX_CHIPLETS = CHIPLET_ID_MAX-CHIPLET_ID_MIN+1; -const uint32_t ASM_RS4_LAUNCH_BUF_SIZE = 24; // Byte size of RS4 launch buffer. +const uint32_t ASM_RS4_LAUNCH_BUF_SIZE = 24; // Byte size of RS4 launch buffer. +const uint32_t WF_ENCAP_SIZE = 400; // Byte size of WF encapsulation. + // (Actually, only 304B but may change.) +const uint32_t WF_WORST_CASE_SIZE_FAC = 3; // WC WF size = 3x ring length. + // (Assumes 12B per write.) const uint32_t LISTING_STRING_SIZE = 256; const uint64_t MAX_UINT64_T = (uint64_t)0xFFFFFFFF<<32 | (uint64_t)0xFFFFFFFF; + +#ifdef __cplusplus +extern "C" { +#endif + // Base (shared) ring layout for both RS4 and Wiggle-flip layouts. typedef struct { - uint64_t entryOffset; - uint64_t backItemPtr; - uint32_t sizeOfThis; - uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated. + uint64_t entryOffset; + uint64_t backItemPtr; + uint32_t sizeOfThis; + uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated. } BaseRingLayout; // RS4 specific layout. @@ -63,14 +73,34 @@ typedef struct { // ring block with its corresponding TOC name. typedef struct { uint64_t address; // (in) Holds PORE backPtr addr of the ring - uint8_t vectorpos; // (in) Vector position of fwdPtr [0;31] - // max=0 for most VPD rings - // max=1 for all non-VPD rings - // max=1 for perv_ VPD rings - // max=15 for most VPD ex_ rings - // max=31 for 16 ex_ chiplets with override + uint8_t vectorpos; // (in) Vector position of fwdPtr [0;31] + // max=0 for most VPD rings + // max=1 for all non-VPD rings + // max=1 for perv_ VPD rings + // max=15 for most VPD ex_ rings + // max=31 for 16 ex_ chiplets with override char *name; // (out) TOC name - uint8_t isvpd; // (out) 0: Non-VPD ring 1: VPD ring - uint8_t overridable; // (out) 0: No (most VPD rings) 1: Yes (all non-VPD rings) + uint8_t isvpd; // (out) 0: Non-VPD ring 1: VPD ring + uint8_t overridable; // (out) 0: No (most VPD rings) 1: Yes (all non-VPD rings) uint8_t override; // (out) 0: base 1: override } PairingInfo; + + +/// +/// **************************************************************************** +/// Function declares. +/// **************************************************************************** +/// +int over_write_ring_data_in_image( void *io_image, + const char *i_ringName, + const void *i_ringData, // WF or RS4 + const uint32_t i_sizeRingData, // Byte size + const uint8_t i_idxVector, + const uint8_t i_override, + const uint8_t i_overridable ); + + +#ifdef __cplusplus +} +#endif + diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H index a777529db..8acb9aaf1 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pore_table_gen_api.H,v 1.15 2012/10/17 19:06:54 cmolsen Exp $ +// $Id: p8_pore_table_gen_api.H,v 1.19 2013/01/31 21:10:10 cmolsen Exp $ /*------------------------------------------------------------------------------*/ /* *! (C) Copyright International Business Machines Corp. 2012 */ /* *! All Rights Reserved -- Property of IBM */ @@ -156,10 +156,11 @@ CONST_UINT64_T( SCRATCH0_RESET_VALUE, (0xABBA99EBBA33DADA) ); //#include <stdio.h> -// Temporarily include this to support malloc until Host services supplies buffers in their calls. #include <stdlib.h> -//#include <stdint.h> +#ifndef __P8_PORE_TABLE_GEN_API_C #include <p8_pore_api_custom.h> +#endif +//#include <stdint.h> //#include <pore_bitmanip.H> // Defining local versions of BITS and BIT @@ -202,8 +203,9 @@ CONST_UINT64_T( SCRATCH0_RESET_VALUE, (0xABBA99EBBA33DADA) ); #define SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME "sub_slw_ex_enable_runtime_scom" #define SCAN_MAX_ROTATE_38XXX_NAME "scan_max_rotate_38xxx" -#define SCAN_ROTATE_DEFAULT 0xFE0 -#define SCAN_MAX_ROTATE 0x1FFF +#define SCAN_ROTATE_DEFAULT 110 // Limit suggested by Tilman. +#define SCAN_MAX_ROTATE 0x00000FE0 +#define SCAN_MAX_ROTATE_LONG 0x000FFFFF // BITS 12->31. // RAM table defines #define XIPSIZE_RAM_ENTRY ( (sizeof(RamTableEntry)+7)/8*8 ) @@ -258,8 +260,19 @@ enum { #define SLW_SCOM_TABLE_OFFSET_L3 (SLW_SCOM_TABLE_OFFSET_L2 + SLW_SCOM_TABLE_SIZE_L2) #define SLW_TABLE_SIZE_ALL (SLW_RAM_TABLE_SIZE + SLW_SCOM_TABLE_SIZE_ALL) -// FFDC section -#define FFDC_SECTION_SIZE 256 +// Enumeration of Scom sections in .slw section. +enum { + P8_SCOM_SECTION_NC = 0, + P8_SCOM_SECTION_L2 = 1, + P8_SCOM_SECTION_L3 = 2, + P8_SCOM_SECTION_MAX_VALUE = 2 +}; + +// SLW section size (Ensure 128-byte alignment.) +#define FIXED_SLW_SECTION_SIZE (SLW_TABLE_SIZE_ALL/128+(SLW_TABLE_SIZE_ALL%128+127)/128)*128 + +// FFDC section size (Ensure 128-byte alignment.) +#define FIXED_FFDC_SECTION_SIZE 256*(SLW_MAX_CORES+1) // SCOM/CID masks and ranges #define P8_CID_EX_LOW 0x10 // Lowest EX chiplet addr @@ -276,6 +289,15 @@ enum { #define P8_PORE_SCOM_LAST_OP 5 // Keep track of the last op for checking correctness of op input +// Enumeration of SLW image build modes. +enum { + P8_SLW_MODEBUILD_IPL = 0, + P8_SLW_MODEBUILD_REBUILD = 1, + P8_SLW_MODEBUILD_SRAM = 2, + P8_SLW_MODEBUILD_MAX_VALUE = 2 +}; + + // Return codes #define SLW_RAM_SUCCESS 0 #define SLW_RAM_HEADERS_NOT_SYNCED 1 @@ -323,7 +345,7 @@ extern const int SLW_SPR_REGS_SIZE; * i_threadId - the thread ID to operate on */ uint32_t p8_pore_gen_cpureg(void *io_image, - uint32_t i_sizeImage, + uint32_t i_sizeImage, uint32_t i_regName, uint64_t i_regData, uint32_t i_coreId, @@ -340,12 +362,48 @@ uint32_t p8_pore_gen_cpureg(void *io_image, * i_section - SCOM section [0,2,3] */ uint32_t p8_pore_gen_scom(void *io_image, - uint32_t i_sizeImage, + uint32_t i_sizeImage, + uint32_t i_scomAddr, + uint32_t i_coreId, + uint64_t i_scomData, + uint32_t i_operation, + uint32_t i_section); + + +/* Name: p8_pore_gen_cpureg_fixed() + * Description: Populates ramming entries in the .slw section + * Parameter list: i_image - pointer to SLW mainstore image + * i_modeBuild - 0: HB/IPL mode, 1: PHYP/Rebuild mode, 2: SRAM mode. + * i_sizeImage - size of SLW mainstore image + * i_regName - unswizzled SPR register value + * i_regData - data to write to SPR register + * i_coreId - the core ID to operate on + * i_threadId - the thread ID to operate on + */ +uint32_t p8_pore_gen_cpureg_fixed(void *io_image, + uint8_t i_modeBuild, + uint32_t i_regName, + uint64_t i_regData, + uint32_t i_coreId, + uint32_t i_threadId); + +/* Name: p8_pore_gen_scom_fixed() + * Description: Populates scom entries in the .slw section + * Parameter list: i_image - pointer to SLW mainstore image + * i_modeBuild - 0: HB/IPL mode, 1: PHYP/Rebuild mode, 2: SRAM mode. + * i_scomAddr - scom register address + * i_coreId - the core ID [0:15] + * i_scomData - 64-bit data to put in scom register + * i_operation - what to do with the scom data [0:5] + * i_section - 0: General Scoms, 1: L2 cache, 2: L3 cache + */ +uint32_t p8_pore_gen_scom_fixed(void *io_image, + uint8_t i_modeBuild, uint32_t i_scomAddr, uint32_t i_coreId, uint64_t i_scomData, uint32_t i_operation, - uint32_t i_section); + uint32_t i_section); #ifdef __cplusplus } diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H index e516afed8..951078ab7 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_ring_identification.H,v 1.6 2012/11/13 16:39:12 cmolsen Exp $ +// $Id: p8_ring_identification.H,v 1.7 2013/02/12 17:33:12 cmolsen Exp $ /*------------------------------------------------------------------------------*/ /* *! (C) Copyright International Business Machines Corp. 2012 */ /* *! All Rights Reserved -- Property of IBM */ @@ -34,16 +34,17 @@ #include <p8_pore_api_custom.h> #include <string.h> // Why isn't this included in p8_pore_api_custom.h? PHYP // said back in Aug that strcmp() is allowed. But it is - // not in p8_pore_api_custom.h. + // not in p8_pore_api_custom.h. // Ring ID list structure. typedef struct { const char *ringName; uint8_t ringId; - uint8_t chipIdMin; - uint8_t chipIdMax; - const char *ringNameImg; // Ring name in image: ringName + "_ring" - uint8_t vpdKeyword; + uint8_t chipIdMin; // the min chipletId + uint8_t chipIdMax; // the max chipletId + const char *ringNameImg; // Ring name in image: ringName + "_ring" + uint8_t vpdKeyword; + uint8_t bWcSpace; // 0: fitted 1: worst-case space (3 x ring length) } RingIdList; extern const RingIdList RING_ID_LIST_PG[], RING_ID_LIST_PR[]; @@ -57,12 +58,12 @@ extern const uint32_t RING_ID_LIST_SIZE; // these values need to be translated in xip_customize when passing the // mvpdKeyword to getMvpdRing(); enum VpdKeyword { - VPD_KEYWORD_PDG, - VPD_KEYWORD_PDR, - NUM_OF_VPD_TYPES + VPD_KEYWORD_PDG, + VPD_KEYWORD_PDR, + NUM_OF_VPD_TYPES }; int get_vpd_ring_list_entry(const char *i_ringName, const uint8_t i_ringId, - RingIdList **i_ringIdList); + RingIdList **i_ringIdList); diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C index fe3429609..bf7a26e29 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_slw_build.C,v 1.9 2013/01/02 02:54:19 cmolsen Exp $ +// $Id: p8_slw_build.C,v 1.10 2013/02/08 02:48:58 cmolsen Exp $ /*------------------------------------------------------------------------------*/ /* *! TITLE : p8_slw_build */ /* *! DESCRIPTION : Extracts and decompresses delta ring states from EPROM */ @@ -34,7 +34,7 @@ /* *! USAGE : To build (for Hostboot) - */ // buildfapiprcd -C "p8_image_help.C,p8_image_help_base.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c" -e "../../xml/error_info/p8_slw_build_errors.xml" p8_slw_build.C // To build (for command-line) - -// buildfapiprcd -r ver-13-0 -C "p8_image_help.C,p8_image_help_base.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c" -e "../../xml/error_info/p8_slw_build_errors.xml" -u "SLW_COMMAND_LINE,IMGBUILD_PPD_IGNORE_XIPC" p8_slw_build.C +// buildfapiprcd -r ver-13-0 -C "p8_image_help.C,p8_image_help_base.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c" -e "../../xml/error_info/p8_slw_build_errors.xml" -u "SLW_COMMAND_LINE,IMGBUILD_PPD_IGNORE_XIPC,IMGBUILD_PPD_WF_POLLING_PROT" p8_slw_build.C // Other Pre-Processor Directive (PPD) options - // To debug WF programs: // -u "IMGBUILD_PPD_DEBUG_WF" @@ -410,7 +410,6 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, } else { FAPI_ERR("ERROR: Nope, couldn't wing it."); - //if (deltaRingDxed) free(deltaRingDxed); if (buf2) free(buf2); uint32_t & RC_LOCAL=rcLoc; FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_UNKNOWN_XIP_ERROR); @@ -424,17 +423,36 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, FAPI_INF("Continuing...\n"); } +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + uint64_t waitsScanDelay=10; + // Temporary support for enforcing delay after scan WF scoms. + // Also remove all references and usages of waitsScanDelay in this file and in + // p8_image_help.C. + rcLoc = sbe_xip_get_scalar( (void*)i_imageIn, "waits_delay_for_scan", &waitsScanDelay); + if (rcLoc) { + FAPI_ERR("Error obtaining waits_delay_for_scan keyword.\n"); + if (buf2) free(buf2); + uint32_t & RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_UNKNOWN_XIP_ERROR); + return rc; + } +#endif + wfInline = (uint32_t*)buf1; wfInlineLenInWords = sizeBuf1/4; - //rcLoc = create_wiggle_flip_prg( (uint32_t*)deltaRingDxed, rcLoc = create_wiggle_flip_prg( (uint32_t*)buf2, ringBitLen, myRev32(deltaRingRS4->iv_scanSelect), (uint32_t)deltaRingRS4->iv_chipletId, &wfInline, &wfInlineLenInWords, +#ifdef IMGBUILD_PPD_ENFORCE_SCAN_DELAY + (uint32_t)scanMaxRotate, + (uint32_t)waitsScanDelay); +#else (uint32_t)scanMaxRotate); - if (rcLoc) { +#endif + if (rcLoc) { FAPI_ERR("create_wiggle_flip_prg() failed w/rcLoc=%i",rcLoc); //if (deltaRingDxed) free(deltaRingDxed); if (buf1) free(buf1); 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 9b3a30746..4ab947f25 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 @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_xip_customize.C,v 1.20 2013/01/04 18:50:27 cmolsen Exp $ +// $Id: p8_xip_customize.C,v 1.25 2013/02/13 01:55:59 cmolsen Exp $ /*------------------------------------------------------------------------------*/ /* *! TITLE : p8_xip_customize */ /* *! DESCRIPTION : Obtains repair rings from VPD and adds them to either */ @@ -33,9 +33,6 @@ // buildfapiprcd -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c" -C "p8_image_help.C,p8_image_help_base.C,p8_scan_compression.C" -e "$PROC_PATH/../../xml/error_info/p8_xip_customize_errors.xml,../../../../../../hwpf/hwp/xml/attribute_info/chip_attributes.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml" p8_xip_customize.C // To build (for VBU/command-line) - assuming getMvpdRing_x86.so already exist. // buildfapiprcd -r ver-13-0 -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c" -C "p8_image_help.C,p8_image_help_base.C,p8_scan_compression.C" -e "../../xml/error_info/p8_xip_customize_errors.xml,../../../../../../hwpf/hwp/xml/attribute_info/chip_attributes.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml" -u "XIPC_COMMAND_LINE" p8_xip_customize.C -// To build (for VBU/command-line) - incorporating getMvpdRing etc into build: -// (NB! Not recommended - it's a mess - the following is incoomplete) -// buildfapiprcd -r ver-13-0 -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c" -C "p8_image_help.C,p8_image_help_base.C,p8_scan_compression.C,getMvpdRing.C" -e "../../xml/error_info/p8_xip_customize_errors.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml,../../../../../../hwpf/hwp/xml/attribute_info/chip_attributes.xml" -u "XIPC_COMMAND_LINE" p8_xip_customize.C // Other usages - // using "IMGBUILD_PPD_IGNORE_VPD" will ignore adding MVPD rings. // using "IMGBUILD_PPD_IGNORE_VPD_FIELD" will ignore using fapiGetMvpdField. @@ -71,20 +68,20 @@ using namespace fapi; // ReturnCode p8_xip_customize( const fapi::Target &i_target, void *i_imageIn, - void *i_imageOut, - uint32_t &io_sizeImageOut, - const uint8_t i_sysPhase, - void *i_buf1, - const uint32_t i_sizeBuf1, - void *i_buf2, - const uint32_t i_sizeBuf2 ) + void *i_imageOut, + uint32_t &io_sizeImageOut, + const uint8_t i_sysPhase, + void *i_buf1, + const uint32_t i_sizeBuf1, + void *i_buf2, + const uint32_t i_sizeBuf2 ) { fapi::ReturnCode rcFapi, rc=FAPI_RC_SUCCESS; - uint32_t rcLoc=0; + uint32_t rcLoc=0; void *imageOut; uint32_t sizeImage, sizeImageIn, sizeImageOutMax; - SBE_XIP_ERROR_STRINGS(errorStrings); + SBE_XIP_ERROR_STRINGS(errorStrings); sizeImageOutMax = io_sizeImageOut; @@ -104,183 +101,207 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, } // Second, if IPL phase, copy input image to supplied mainstore location. - // - if (i_sysPhase==0) { - imageOut = i_imageOut; - memcpy( imageOut, i_imageIn, sizeImageIn); - sbe_xip_image_size(imageOut, &sizeImage); - rcLoc = sbe_xip_validate(imageOut, sizeImage); - if (rcLoc) { - FAPI_ERR("xip_validate() failed w/rcLoc=%i",rcLoc); - uint32_t & RC_LOCAL=rcLoc; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_MS_INTERNAL_IMAGE_ERR); - return rc; - } - if (sizeImage!=sizeImageIn) { - FAPI_ERR("Size obtained from image's header (=%i) differs from supplied size (=%i).", - sizeImage,sizeImageIn); - uint32_t & DATA_IMG_SIZE_INP = sizeImageIn; - uint32_t & DATA_IMG_SIZE = sizeImage; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_MS_IMAGE_SIZE_MISMATCH); - return rc; - } - FAPI_DBG("IPL phase: Input image (w/location=0x%016llx) copied to output image and validated w/size=%i bytes and location=0x%016llx", - (uint64_t)i_imageIn, sizeImageIn, (uint64_t)imageOut); - } - else // Output image is same as input image in SLW case (even for an SRAM build). - imageOut = i_imageIn; + // + if (i_sysPhase==0) { + imageOut = i_imageOut; + memcpy( imageOut, i_imageIn, sizeImageIn); + sbe_xip_image_size(imageOut, &sizeImage); + rcLoc = sbe_xip_validate(imageOut, sizeImage); + if (rcLoc) { + FAPI_ERR("xip_validate() failed w/rcLoc=%i",rcLoc); + uint32_t & RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_MS_INTERNAL_IMAGE_ERR); + return rc; + } + if (sizeImage!=sizeImageIn) { + FAPI_ERR("Size obtained from image's header (=%i) differs from supplied size (=%i).", + sizeImage,sizeImageIn); + uint32_t & DATA_IMG_SIZE_INP = sizeImageIn; + uint32_t & DATA_IMG_SIZE = sizeImage; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_MS_IMAGE_SIZE_MISMATCH); + return rc; + } + FAPI_DBG("IPL phase: Input image (w/location=0x%016llx) copied to output image and validated w/size=%i bytes and location=0x%016llx", + (uint64_t)i_imageIn, sizeImageIn, (uint64_t)imageOut); + } + else // Output image is same as input image in SLW case (even for an SRAM build). + imageOut = i_imageIn; // Customization defines. // - uint32_t iVec=0; - uint64_t attrCombGoodVec[MAX_CHIPLETS]={ (uint64_t(0xfedcba98)<<32)+0x76543210 }; - void *hostCombGoodVec; - SbeXipItem xipTocItem; - - // -------------------------------------------------------------------------- - // CUSTOMIZE item: Combined good vectors update. - // Retrieval method: Attribute. - // System phase: IPL and SLW sysPhase. - // Note: The 32 vectors are listed in order from chiplet 0x00 to 0x1f. - // Note: We will use the content of these vectors to determine if each - // chiplet is functional. This is to avoid the messy "walking the - // chiplets approach" using fapiGetChildChiplets(). - // -------------------------------------------------------------------------- - - rc = FAPI_ATTR_GET(ATTR_CHIP_REGIONS_TO_ENABLE, &i_target, attrCombGoodVec); - if (rc) { - FAPI_ERR("FAPI_ATTR_GET(ATTR_CHIP_REGIONS_TO_ENABLE) returned error.\n"); - return rc; - } - rcLoc = sbe_xip_find( imageOut, COMBINED_GOOD_VECTORS_TOC_NAME, &xipTocItem); - if (rcLoc) { + uint32_t iVec=0; + uint64_t attrCombGoodVec[MAX_CHIPLETS]={ (uint64_t(0xfedcba98)<<32)+0x76543210 }; + void *hostCombGoodVec; + uint32_t attrL2SingleMember=0; + void *hostL2SingleMember; + SbeXipItem xipTocItem; + + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Combined good vectors update. + // Retrieval method: Attribute. + // System phase: IPL and SLW sysPhase. + // Note: The 32 vectors are listed in order from chiplet 0x00 to 0x1f. + // Note: We will use the content of these vectors to determine if each + // chiplet is functional. This is to avoid the messy "walking the + // chiplets approach" using fapiGetChildChiplets(). + // -------------------------------------------------------------------------- + + rc = FAPI_ATTR_GET(ATTR_CHIP_REGIONS_TO_ENABLE, &i_target, attrCombGoodVec); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_CHIP_REGIONS_TO_ENABLE) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( imageOut, COMBINED_GOOD_VECTORS_TOC_NAME, &xipTocItem); + if (rcLoc) { FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); FAPI_ERR("Probable cause:"); FAPI_ERR("\tThe keyword (=%s) was not found.",COMBINED_GOOD_VECTORS_TOC_NAME); uint32_t & RC_LOCAL = rcLoc; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); - return rc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostCombGoodVec); + FAPI_DBG("Dumping [initial] global variable content of combined_good_vectors, then the updated value:\n"); + for (iVec=0; iVec<MAX_CHIPLETS; iVec++) { + FAPI_DBG("combined_good_vectors[%2i]: Before=0x%016llX\n",iVec,*((uint64_t*)hostCombGoodVec+iVec)); + *((uint64_t*)hostCombGoodVec+iVec) = myRev64(attrCombGoodVec[iVec]); + FAPI_DBG(" After=0x%016llX\n",*((uint64_t*)hostCombGoodVec+iVec)); + } + // -------------------------------------------------------------------------- + // CUSTOMIZE item: L2 "single member mode" enable. + // Retrieval method: Attribute. + // System phase: IPL and SLW sysPhase. + // Note: The 32 vectors are listed in order from chiplet 0x00 to 0x1f. + // Note: We will use the content of these vectors to determine if each + // chiplet is functional. This is to avoid the messy "walking the + // chiplets approach" using fapiGetChildChiplets(). + // -------------------------------------------------------------------------- + + rc = FAPI_ATTR_GET(ATTR_EX_L2_SINGLE_MEMBER_ENABLE, &i_target, attrL2SingleMember); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_EX_L2_SINGLE_MEMBER_ENABLE) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( imageOut, L2_SINGLE_MEMBER_ENABLE_TOC_NAME, &xipTocItem); + if (rcLoc) { + FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_ERR("Probable cause:"); + FAPI_ERR("\tThe keyword (=%s) was not found.",L2_SINGLE_MEMBER_ENABLE_TOC_NAME); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; } - sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostCombGoodVec); - FAPI_DBG("Dumping [initial] global variable content of combined_good_vectors, then the updated value:\n"); - for (iVec=0; iVec<MAX_CHIPLETS; iVec++) { - FAPI_INF("combined_good_vectors[%2i]: Before=0x%016llX",iVec,*((uint64_t*)hostCombGoodVec+iVec)); - *((uint64_t*)hostCombGoodVec+iVec) = myRev64(attrCombGoodVec[iVec]); - FAPI_INF(" After=0x%016llX\n",*((uint64_t*)hostCombGoodVec+iVec)); - } + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostL2SingleMember); + FAPI_DBG("Dumping [initial] global variable content of l2_single_member_enable_mask, and then the updated value:\n"); + FAPI_DBG("l2_single_member_enable_mask: Before=0x%016llX\n",*(uint64_t*)hostL2SingleMember); + *(uint64_t*)hostL2SingleMember = (uint64_t)myRev32(attrL2SingleMember); + FAPI_DBG(" After =0x%016llX\n",*(uint64_t*)hostL2SingleMember); #ifndef IMGBUILD_PPD_IGNORE_VPD_FIELD - void *hostPibmemRepairVec, *hostNestSkewAdjVec; - uint8_t *bufVpdField; - uint32_t sizeVpdField=0; + void *hostPibmemRepairVec, *hostNestSkewAdjVec; + uint8_t *bufVpdField; + uint32_t sizeVpdField=0; uint8_t *byteField, *byteVector; // -------------------------------------------------------------------------- - // CUSTOMIZE item: Update 20 swizzled bits for PIB repair vector. - // Retrieval method: MVPD field. - // System phase: IPL sysPhase. - // -------------------------------------------------------------------------- - if (i_sysPhase==0) { - bufVpdField = (uint8_t*)i_buf1; - sizeVpdField = i_sizeBuf1; // We have to use fixed and max size buffer. - rcFapi = fapiGetMvpdField( MVPD_RECORD_CP00, - MVPD_KEYWORD_PB, - i_target, - bufVpdField, - sizeVpdField); - if (rcFapi) { - FAPI_ERR("fapiGetMvpdField() w/keyword=PB returned error."); - return rcFapi; + // CUSTOMIZE item: Update 20 swizzled bits for PIB repair vector. + // Retrieval method: MVPD field. + // System phase: IPL sysPhase. + // -------------------------------------------------------------------------- + if (i_sysPhase==0) { + bufVpdField = (uint8_t*)i_buf1; + sizeVpdField = i_sizeBuf1; // We have to use fixed and max size buffer. + rcFapi = fapiGetMvpdField( MVPD_RECORD_CP00, + MVPD_KEYWORD_PB, + i_target, + bufVpdField, + sizeVpdField); + if (rcFapi) { + FAPI_ERR("fapiGetMvpdField() w/keyword=PB returned error."); + return rcFapi; } - rcLoc = sbe_xip_find( imageOut, PROC_PIB_REPR_VECTOR_TOC_NAME, &xipTocItem); - if (rcLoc) { - FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); - FAPI_ERR("Probable cause:"); - FAPI_ERR("\tThe keyword (=%s) was not found.",PROC_PIB_REPR_VECTOR_TOC_NAME); - uint32_t & RC_LOCAL = rcLoc; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); - return rc; - } - if (sizeVpdField!=5) { - if (sizeVpdField==4) { - FAPI_INF("fapiGetMvpdField() w/keyword=PB returned sizeVpdField=%i but we expected size=5.",sizeVpdField); - FAPI_INF("This is a temporary inconsistency. We will continue for now even though unreliable operation may ensue."); - } - else { - FAPI_ERR("fapiGetMvpdField() w/keyword=PB returned sizeVpdField=%i but we expected size=5.",sizeVpdField); - uint32_t & DATA_SIZE_VPD_FIELD = sizeVpdField; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE); - return rc; - } - } - FAPI_DBG("Dumping global variable content of pibmem_repair_vector:\n"); - sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostPibmemRepairVec); - FAPI_INF("pibmem_repair_vector:Before (in BE)=0x%016llX\n",*(uint64_t*)hostPibmemRepairVec); + rcLoc = sbe_xip_find( imageOut, PROC_PIB_REPR_VECTOR_TOC_NAME, &xipTocItem); + if (rcLoc) { + FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_ERR("Probable cause:"); + FAPI_ERR("\tThe keyword (=%s) was not found.",PROC_PIB_REPR_VECTOR_TOC_NAME); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (sizeVpdField!=5) { + FAPI_ERR("fapiGetMvpdField() w/keyword=PB returned sizeVpdField=%i but we expected size=5.",sizeVpdField); + uint32_t & DATA_SIZE_VPD_FIELD = sizeVpdField; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE); + return rc; + } + FAPI_DBG("Dumping global variable content of pibmem_repair_vector:\n"); + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostPibmemRepairVec); + FAPI_INF("pibmem_repair_vector:Before (in BE)=0x%016llX\n",*(uint64_t*)hostPibmemRepairVec); byteField = (uint8_t*)bufVpdField; - byteVector = (uint8_t*)hostPibmemRepairVec; - // Copy the bytes over one by one, skipping first byte (version indicator). - *(byteVector+0) = *(byteField+1); - *(byteVector+1) = *(byteField+2); - *(byteVector+2) = *(byteField+3); - if (sizeVpdField==5) // Eventually remove this if-line. - *(byteVector+3) = *(byteField+4); - FAPI_INF(" After (in BE)=0x%016llX\n",*(uint64_t*)hostPibmemRepairVec); - FAPI_INF("VPD field value (unalterd & in BE))=0x%016llX\n",*(uint64_t*)bufVpdField); - } + byteVector = (uint8_t*)hostPibmemRepairVec; + // Copy the bytes over one by one, skipping first byte (version indicator). + *(byteVector+0) = *(byteField+1); + *(byteVector+1) = *(byteField+2); + *(byteVector+2) = *(byteField+3); + *(byteVector+3) = *(byteField+4); + FAPI_INF(" After (in BE)=0x%016llX\n",*(uint64_t*)hostPibmemRepairVec); + FAPI_INF("VPD field value (unalterd & in BE))=0x%016llX\n",*(uint64_t*)bufVpdField); + } // -------------------------------------------------------------------------- - // CUSTOMIZE item: Update nest skewadjust vector. - // Retrieval method: MVPD field. - // System phase: IPL sysPhase. - // -------------------------------------------------------------------------- - if (i_sysPhase==0) { - bufVpdField = (uint8_t*)i_buf1; - sizeVpdField = i_sizeBuf1; // We have to use fixed and max size buffer. - rcFapi = fapiGetMvpdField( MVPD_RECORD_CP00, - MVPD_KEYWORD_MK, - i_target, - bufVpdField, - sizeVpdField); - if (rcFapi) { - FAPI_ERR("fapiGetMvpdField() w/keyword=MK returned error."); - return rcFapi; + // CUSTOMIZE item: Update nest skewadjust vector. + // Retrieval method: MVPD field. + // System phase: IPL sysPhase. + // -------------------------------------------------------------------------- + if (i_sysPhase==0) { + bufVpdField = (uint8_t*)i_buf1; + sizeVpdField = i_sizeBuf1; // We have to use fixed and max size buffer. + rcFapi = fapiGetMvpdField( MVPD_RECORD_CP00, + MVPD_KEYWORD_MK, + i_target, + bufVpdField, + sizeVpdField); + if (rcFapi) { + FAPI_ERR("fapiGetMvpdField() w/keyword=MK returned error."); + return rcFapi; } - rcLoc = sbe_xip_find( imageOut, NEST_SKEWADJUST_VECTOR_TOC_NAME, &xipTocItem); - if (rcLoc) { - FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); - FAPI_ERR("Probable cause:"); - FAPI_ERR("\tThe keyword (=%s) was not found.",NEST_SKEWADJUST_VECTOR_TOC_NAME); - uint32_t & RC_LOCAL = rcLoc; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); - return rc; - } - if (sizeVpdField!=5) { - FAPI_ERR("fapiGetMvpdField() w/keyword=MK returned sizeVpdField=%i but expected size=5.",sizeVpdField); - uint32_t & DATA_SIZE_VPD_FIELD = sizeVpdField; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE); - return rc; - } - FAPI_DBG("Dumping global variable content of nest_skewadjust_vector:\n"); - sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostNestSkewAdjVec); - FAPI_INF("nest_skewadjust_vector: Before (in BE)=0x%016llX\n",*((uint64_t*)hostNestSkewAdjVec)); + rcLoc = sbe_xip_find( imageOut, NEST_SKEWADJUST_VECTOR_TOC_NAME, &xipTocItem); + if (rcLoc) { + FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_ERR("Probable cause:"); + FAPI_ERR("\tThe keyword (=%s) was not found.",NEST_SKEWADJUST_VECTOR_TOC_NAME); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (sizeVpdField!=5) { + FAPI_ERR("fapiGetMvpdField() w/keyword=MK returned sizeVpdField=%i but we expected size=5.",sizeVpdField); + uint32_t & DATA_SIZE_VPD_FIELD = sizeVpdField; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE); + return rc; + } + FAPI_DBG("Dumping global variable content of nest_skewadjust_vector:\n"); + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostNestSkewAdjVec); + FAPI_INF("nest_skewadjust_vector: Before (in BE)=0x%016llX\n",*((uint64_t*)hostNestSkewAdjVec)); byteField = (uint8_t*)bufVpdField; - byteVector = (uint8_t*)hostNestSkewAdjVec; - // Copy the bytes over one by one, skipping first byte (version indicator). - *(byteVector+0) = *(byteField+1); - *(byteVector+1) = *(byteField+2); - *(byteVector+2) = *(byteField+3); - *(byteVector+3) = *(byteField+4); - FAPI_INF(" After (in BE)=0x%016llX\n",*(uint64_t*)hostNestSkewAdjVec); - FAPI_INF("VPD field value (unaltered & in BE) =0x%016llX\n",*(uint64_t*)bufVpdField); - } + byteVector = (uint8_t*)hostNestSkewAdjVec; + // Copy the bytes over one by one, skipping first byte (version indicator). + *(byteVector+0) = *(byteField+1); + *(byteVector+1) = *(byteField+2); + *(byteVector+2) = *(byteField+3); + *(byteVector+3) = *(byteField+4); + FAPI_INF(" After (in BE)=0x%016llX\n",*(uint64_t*)hostNestSkewAdjVec); + FAPI_INF("VPD field value (unaltered & in BE) =0x%016llX\n",*(uint64_t*)bufVpdField); + } #endif #ifndef IMGBUILD_PPD_IGNORE_PLL_UPDATE // -------------------------------------------------------------------------- - // CUSTOMIZE item: Update PLL ring (perv_bndy_pll_ring_alt). - // Retrieval method: Attribute. - // System phase: IPL sysPhase. - // -------------------------------------------------------------------------- + // CUSTOMIZE item: Update PLL ring (perv_bndy_pll_ring_alt). + // Retrieval method: Attribute. + // System phase: IPL sysPhase. + // -------------------------------------------------------------------------- if (i_sysPhase==0) { uint32_t tmp32Const1, tmp32Const2; @@ -293,26 +314,23 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, uint32_t sizeDeltaPllRingAlt=0; uint32_t sizeRs4Launch=0; uint8_t *bufDeltaPllRingAlt; -// uint64_t xipPllRingBlock; -// void *hostPllRingBlock; -// CompressedScanData *hostPllRingRs4; CompressedScanData *bufPllRingAltRs4; uint32_t sizePllRingAltRs4Max, sizePllRingAltRs4, sizePllRingAltBlockMax; - DeltaRingLayout *bufPllRingAltBlock; - uint32_t bufLC=0; + DeltaRingLayout *bufPllRingAltBlock; + uint32_t bufLC=0; // // Retrieve the raw PLL rings state from attributes. // - FAPI_INF("XIPC: PLL update: Retrieve the raw PLL ring state from attributes."); + FAPI_INF("XIPC: 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_DBG("XIPC: PLL update: PLL ring length (bits) = %i",attrRingDataSize); - FAPI_DBG("XIPC: PLL update: Size of buf1, i_sizeBuf1 (bytes) = %i",i_sizeBuf1); - if (rc) { - FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_LENGTH) returned error."); - return rc; - } + FAPI_DBG("XIPC: PLL update: Size of buf1, i_sizeBuf1 (bytes) = %i",i_sizeBuf1); + if (rc) { + 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) { FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_LENGTH) returned ring size =%i bits.\n", attrRingDataSize); @@ -325,139 +343,133 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, 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; + 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_PERV_BNDY_PLL_FLUSH, &i_target, attrRingFlush); - if (rc) { - FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_FLUSH) returned error."); - return rc; - } - rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_DATA, &i_target, attrRingData); - if (rc) { - FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_DATA) returned error."); - return rc; - } - rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_CHIPLET_ID, &i_target, attrChipletId); - if (rc) { - FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_CHIPLET_ID) returned error."); -// return rc; - FAPI_ERR("...but in all likelyhood, it's because the data isn't in Cronus yet."); - FAPI_ERR("So, hardcoding chipletId to =0xFF for now...and continuing."); - attrChipletId = 0xFF; - } - rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_SCAN_SELECT, &i_target, attrScanSelect); - if (rc) { - FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_SCAN_SELECT) returned error."); -// return rc; - FAPI_ERR("...but in all likelyhood, it's because the data isn't in Cronus yet."); - FAPI_ERR("So, hardcoding scanSelect to =0x00100008 for now...and continuing."); - attrScanSelect = 0x00100008; - } - - // - // Calculate the delta scan ring. - // - FAPI_INF("XIPC: PLL update: Calculate the delta scan ring."); - bufDeltaPllRingAlt = (uint8_t*)i_buf1; + rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_FLUSH, &i_target, attrRingFlush); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_FLUSH) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_DATA, &i_target, attrRingData); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_DATA) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_CHIPLET_ID, &i_target, attrChipletId); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_CHIPLET_ID) returned error."); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_PROC_PERV_BNDY_PLL_SCAN_SELECT, &i_target, attrScanSelect); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_PROC_PERV_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 ); + (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; + 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, - 0 ); - 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; + 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, + 0 ); + 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."); + 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; + 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."); + 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( 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."); + rcLoc = sbe_xip_get_scalar( 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."); + 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); + 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); + 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; - + 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. // @@ -465,280 +477,282 @@ ReturnCode p8_xip_customize( const fapi::Target &i_target, 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->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; rc = FAPI_ATTR_GET_PRIVILEGED(ATTR_EC, &i_target, attrDdLevel); if (rc) { FAPI_ERR("FAPI_ATTR_GET_PRIVILEGED() failed w/rc=%i and ddLevel=0x%02x",(uint32_t)rc,attrDdLevel); return rc; } - bufPllRingAltBlock->ddLevel = (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); + bufPllRingAltBlock->ddLevel = (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:"); + 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); + 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; - } + 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. // - FAPI_INF("XIPC: PLL update: Appending RS4 PLL ring block to .rings section."); - rcLoc = write_ring_block_to_image( imageOut, - PERV_BNDY_PLL_RING_ALT_TOC_NAME, - bufPllRingAltBlock, - 0, - 0, - 0, - sizeImageOutMax ); + FAPI_INF("XIPC: PLL update: Appending RS4 PLL ring block to .rings section."); + rcLoc = write_ring_block_to_image( imageOut, + PERV_BNDY_PLL_RING_ALT_TOC_NAME, + bufPllRingAltBlock, + 0, + 0, + 0, + sizeImageOutMax ); if (rcLoc) { - FAPI_ERR("write_ring_block_to_image() failed 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); - } + FAPI_ERR("write_ring_block_to_image() failed 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; + } } #endif #ifndef IMGBUILD_PPD_IGNORE_VPD - // -------------------------------------------------------------------------- - // CUSTOMIZE item: Add #G and #R rings. - // Applies to both sysPhase modes: IPL and SLW. - // For SLW, only update ex_ chiplet rings. - // -------------------------------------------------------------------------- - - /*************************************************************************** + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Add #G and #R rings. + // Applies to both sysPhase modes: IPL and SLW. + // For SLW, only update ex_ chiplet rings. + // -------------------------------------------------------------------------- + + /*************************************************************************** * CHIPLET WALK LOOP - Begin * ***************************************************************************/ - // - // Walk through #G rings first, then #R rings. - // iVpdType=0 : #G Repair rings - // iVpdType=1 : #R Repair rings - // Notes about VPD rings: - // - Only space for the base ring is allocated in the TOC. No override space! - // - Some ex_ rings are non-core-ID-specific and will have chipletID=0xFF. - // Add these rings only once!! - // Notes about #G rings: - // - Some ex_ rings are core ID specific. Add the fwd ptr based on the core ID. - // Notes about $R rings: - // - The ex_ rings are core ID specific. Add the fwd ptr based on the core ID. - // - uint8_t iVpdType; - RingIdList *ring_id_list=NULL; - uint32_t ring_id_list_size; - uint32_t iRing; - uint32_t sizeVpdRing=0; - uint8_t chipletId, ringId; - uint8_t *bufVpdRing; - uint32_t ddLevel=0xFFFFFFFF; - uint8_t bValidChipletId=0,bRingAlreadyAdded=0; - uint8_t chipletIdVpd; - uint32_t sizeImageOut; - - for (iVpdType=0; iVpdType<NUM_OF_VPD_TYPES; iVpdType++) { + // + // Walk through #G rings first, then #R rings. + // iVpdType=0 : #G Repair rings + // iVpdType=1 : #R Repair rings + // Notes about VPD rings: + // - Only space for the base ring is allocated in the TOC. No override space! + // - Some ex_ rings are non-core-ID-specific and will have chipletID=0xFF. + // Add these rings only once!! + // Notes about #G rings: + // - Some ex_ rings are core ID specific. Add the fwd ptr based on the core ID. + // Notes about $R rings: + // - The ex_ rings are core ID specific. Add the fwd ptr based on the core ID. + // + uint8_t iVpdType; + RingIdList *ring_id_list=NULL; + uint32_t ring_id_list_size; + uint32_t iRing; + uint32_t sizeVpdRing=0; + uint8_t chipletId, ringId; + uint8_t *bufVpdRing; + uint32_t ddLevel=0xFFFFFFFF; + uint8_t bValidChipletId=0,bRingAlreadyAdded=0; + uint8_t chipletIdVpd; + uint32_t sizeImageOut; + + for (iVpdType=0; iVpdType<NUM_OF_VPD_TYPES; iVpdType++) { if (iVpdType==0) { - ring_id_list = (RingIdList*)RING_ID_LIST_PG; - ring_id_list_size = (uint32_t)RING_ID_LIST_PG_SIZE; - } - else { - ring_id_list = (RingIdList*)RING_ID_LIST_PR; - ring_id_list_size = (uint32_t)RING_ID_LIST_PR_SIZE; - } + ring_id_list = (RingIdList*)RING_ID_LIST_PG; + ring_id_list_size = (uint32_t)RING_ID_LIST_PG_SIZE; + } + else { + ring_id_list = (RingIdList*)RING_ID_LIST_PR; + ring_id_list_size = (uint32_t)RING_ID_LIST_PR_SIZE; + } - for (iRing=0; iRing<ring_id_list_size; iRing++) { - ringId = (ring_id_list+iRing)->ringId; - bRingAlreadyAdded = 0; - for ( chipletId=(ring_id_list+iRing)->chipIdMin; - (chipletId>=(ring_id_list+iRing)->chipIdMin && chipletId<=(ring_id_list+iRing)->chipIdMax); - chipletId++) { - FAPI_INF("(iRing,ringId,chipletId) = (%i,0x%02X,0x%02x)",iRing,ringId,chipletId); - bValidChipletId = 0; - if (chipletId>=CHIPLET_ID_MIN && chipletId<=CHIPLET_ID_MAX) { - // Using known_good_vectors data to determine if a chiplet is functional. - if (attrCombGoodVec[chipletId]) - bValidChipletId = 1; - else - bValidChipletId = 0; - } - else { - if (chipletId==0xFF) - bValidChipletId = 1; - else { - bValidChipletId = 0; - FAPI_INF("chipletId=0x%02x is not a valid chiplet ID. Check chiplet ID range in p8_ring_identification.c.",chipletId); - } - } - if (bValidChipletId) { - bufVpdRing = (uint8_t*)i_buf1; - sizeVpdRing = i_sizeBuf1; // We always supply max buffer space for ring. - // 2012-11-14: CMO- A thought: Once getMvpdRing() becomes available, add - // get_mvpd_keyword() func at bottom in this file. Then - // put prototype in *.H file. The func should map the - // vpd keyword (0,1,2,...) to mvpd keyword in the include - // file, fapiMvpdAccess.H. - //rcFapi = get_mvpd_keyword((ring_id_list+iRing)->vpdKeyword, mvpdKeyword); - //if (rcFapi) { - // FAPI_ERR("get_mvpd_keyword() returned error."); - // return rcFapi; - //} - fapi::MvpdKeyword mvpd_keyword; - if ((ring_id_list+iRing)->vpdKeyword==VPD_KEYWORD_PDG) - mvpd_keyword = MVPD_KEYWORD_PDG; - else - if ((ring_id_list+iRing)->vpdKeyword==VPD_KEYWORD_PDR) - mvpd_keyword = MVPD_KEYWORD_PDR; - else { - FAPI_ERR("Unable to resolve VPD keyword from ring list table."); - uint8_t & DATA_RING_LIST_VPD_KEYWORD = (ring_id_list+iRing)->vpdKeyword; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_VPD_KEYWORD_RESOLVE_ERROR); - return rc; - } - rcFapi = FAPI_RC_SUCCESS; - FAPI_EXEC_HWP(rcFapi, getMvpdRing, - MVPD_RECORD_CP00, - mvpd_keyword, - i_target, - chipletId, - ringId, - bufVpdRing, - sizeVpdRing); - FAPI_DBG("XIPC: Mvpd rings: rcFapi=0x%08x",(uint32_t)rcFapi); - FAPI_DBG("XIPC: Mvpd rings: RC_REPAIR_RING_NOT_FOUND=0x%08x",(uint32_t)RC_REPAIR_RING_NOT_FOUND); - if (rcFapi==RC_REPAIR_RING_NOT_FOUND) { - // No match, do nothing. Next (chipletId,ringId)-pair. - FAPI_INF("XIPC: Mvpd rings: (iRing,ringId,chipletId)=(%i,0x%02X,0x%02X) not found.",iRing,ringId,chipletId); - } - else { + for (iRing=0; iRing<ring_id_list_size; iRing++) { + ringId = (ring_id_list+iRing)->ringId; + bRingAlreadyAdded = 0; + for ( chipletId=(ring_id_list+iRing)->chipIdMin; + (chipletId>=(ring_id_list+iRing)->chipIdMin && chipletId<=(ring_id_list+iRing)->chipIdMax); + chipletId++) { + FAPI_INF("(iRing,ringId,chipletId) = (%i,0x%02X,0x%02x)",iRing,ringId,chipletId); + bValidChipletId = 0; + if (chipletId>=CHIPLET_ID_MIN && chipletId<=CHIPLET_ID_MAX) { + // Using known_good_vectors data to determine if a chiplet is functional. + if (attrCombGoodVec[chipletId]) + bValidChipletId = 1; + else + bValidChipletId = 0; + } + else { + if (chipletId==0xFF) + bValidChipletId = 1; + else { + bValidChipletId = 0; + FAPI_INF("chipletId=0x%02x is not a valid chiplet ID. Check chiplet ID range in p8_ring_identification.c.",chipletId); + } + } + if (bValidChipletId) { + bufVpdRing = (uint8_t*)i_buf1; + sizeVpdRing = i_sizeBuf1; // We always supply max buffer space for ring. + // 2012-11-14: CMO- A thought: Once getMvpdRing() becomes available, add + // get_mvpd_keyword() func at bottom in this file. Then + // put prototype in *.H file. The func should map the + // vpd keyword (0,1,2,...) to mvpd keyword in the include + // file, fapiMvpdAccess.H. + //rcFapi = get_mvpd_keyword((ring_id_list+iRing)->vpdKeyword, mvpdKeyword); + //if (rcFapi) { + // FAPI_ERR("get_mvpd_keyword() returned error."); + // return rcFapi; + //} + fapi::MvpdKeyword mvpd_keyword; + if ((ring_id_list+iRing)->vpdKeyword==VPD_KEYWORD_PDG) + mvpd_keyword = MVPD_KEYWORD_PDG; + else + if ((ring_id_list+iRing)->vpdKeyword==VPD_KEYWORD_PDR) + mvpd_keyword = MVPD_KEYWORD_PDR; + else { + FAPI_ERR("Unable to resolve VPD keyword from ring list table."); + uint8_t & DATA_RING_LIST_VPD_KEYWORD = (ring_id_list+iRing)->vpdKeyword; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_VPD_KEYWORD_RESOLVE_ERROR); + return rc; + } + rcFapi = FAPI_RC_SUCCESS; + FAPI_EXEC_HWP(rcFapi, getMvpdRing, + MVPD_RECORD_CP00, + mvpd_keyword, + i_target, + chipletId, + ringId, + bufVpdRing, + sizeVpdRing); + FAPI_DBG("XIPC: Mvpd rings: rcFapi=0x%08x",(uint32_t)rcFapi); + //FAPI_DBG("XIPC: Mvpd rings: RC_REPAIR_RING_NOT_FOUND=0x%08x",(uint32_t)RC_REPAIR_RING_NOT_FOUND); + if (rcFapi==RC_REPAIR_RING_NOT_FOUND) { + // No match, do nothing. Next (chipletId,ringId)-pair. + FAPI_INF("XIPC: Mvpd rings: (iRing,ringId,chipletId)=(%i,0x%02X,0x%02X) not found.",iRing,ringId,chipletId); + } + else { // Couple of other checks... // 1. General rc error check. - if (rcFapi!=FAPI_RC_SUCCESS) { - FAPI_ERR("getMvpdRing() returned error."); - return rcFapi; - } - // 2. Checking that chipletId didn't somehow get messed up. - chipletIdVpd = ((CompressedScanData*)bufVpdRing)->iv_chipletId; - if (chipletIdVpd!=chipletId && chipletIdVpd!=0xFF) { - FAPI_ERR("VPD ring's chipletId in scan container (=0x%02X) is not equal to 0xFF nor does it match the requested chipletId (=0x%02X).\n",chipletIdVpd,chipletId); - uint8_t & DATA_CHIPLET_ID_VPD = chipletIdVpd; - uint8_t & DATA_CHIPLET_ID_REQ = chipletId; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_CHIPLET_ID_MESS); - return rc; - } - // 3. Checking for buffer overflow. - if (sizeVpdRing>i_sizeBuf1) { - // Supplied buffer from HB/PHYP is too small. Error out. Is this right - // decision or should we ignore and proceed to next ring. - uint32_t sizeBuf1=(uint32_t)i_sizeBuf1; - uint32_t & DATA_RING_SIZE_REQ = sizeVpdRing; - uint32_t & DATA_RING_SIZE_MAX = sizeBuf1; - switch (iVpdType) { - case 0: - FAPI_ERR("#G ring too large."); - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PG_RING_TOO_LARGE); - break; - case 1: - FAPI_ERR("#R ring too large."); - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PR_RING_TOO_LARGE); - break; - default: - uint8_t & DATA_VPD_TYPE = iVpdType; - FAPI_ERR("#Invalid VPD type."); - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_INVALID_VPD_TYPE); - break; - } - return rc; - } - else { - // Add VPD ring to image. - if (!bRingAlreadyAdded) { - sizeImageOut = sizeImageOutMax; - rcLoc = 0; - if (i_sysPhase==0) { - // Add VPD ring to --->>> IPL <<<--- image - rcLoc = write_vpd_ring_to_ipl_image( - imageOut, - sizeImageOut, - (CompressedScanData*)bufVpdRing, //HB buf1 - ddLevel, - i_sysPhase, - (char*)((ring_id_list+iRing)->ringNameImg), - (void*)i_buf2, //HB buf2 - i_sizeBuf2); - } - else { - // Add VPD ring to --->>> SLW <<<--- image - rcLoc = write_vpd_ring_to_slw_image( - imageOut, - sizeImageOut, - (CompressedScanData*)bufVpdRing, //HB buf1 - ddLevel, - i_sysPhase, - (char*)(ring_id_list+iRing)->ringNameImg, - (void*)i_buf2, //HB buf2 - i_sizeBuf2); - } - if (rcLoc) { - if (i_sysPhase==0) { - FAPI_ERR("write_vpd_ring_to_ipl_image() failed w/rc=%i",rcLoc); - } - else { - FAPI_ERR("write_vpd_ring_to_slw_image() failed w/rc=%i",rcLoc); - } - uint32_t & RC_LOCAL = rcLoc; - FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_WRITE_VPD_RING_TO_IMAGE_ERROR); - return rc; - } - if (chipletIdVpd==0xFF) - bRingAlreadyAdded = 1; - } - } - } - } - } - } + if (rcFapi!=FAPI_RC_SUCCESS) { + FAPI_ERR("getMvpdRing() returned error."); + return rcFapi; + } + // 2. Checking that chipletId didn't somehow get messed up. + chipletIdVpd = ((CompressedScanData*)bufVpdRing)->iv_chipletId; + if (chipletIdVpd!=chipletId && chipletIdVpd!=0xFF) { + FAPI_ERR("VPD ring's chipletId in scan container (=0x%02X) is not equal to 0xFF nor does it match the requested chipletId (=0x%02X).\n",chipletIdVpd,chipletId); + uint8_t & DATA_CHIPLET_ID_VPD = chipletIdVpd; + uint8_t & DATA_CHIPLET_ID_REQ = chipletId; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_CHIPLET_ID_MESS); + return rc; + } + // 3. Checking for buffer overflow. + if (sizeVpdRing>i_sizeBuf1) { + // Supplied buffer from HB/PHYP is too small. Error out. Is this right + // decision or should we ignore and proceed to next ring. + uint32_t sizeBuf1=(uint32_t)i_sizeBuf1; + uint32_t & DATA_RING_SIZE_REQ = sizeVpdRing; + uint32_t & DATA_RING_SIZE_MAX = sizeBuf1; + switch (iVpdType) { + case 0: + FAPI_ERR("#G ring too large."); + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PG_RING_TOO_LARGE); + break; + case 1: + FAPI_ERR("#R ring too large."); + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PR_RING_TOO_LARGE); + break; + default: + uint8_t & DATA_VPD_TYPE = iVpdType; + FAPI_ERR("#Invalid VPD type."); + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_INVALID_VPD_TYPE); + break; + } + return rc; + } + else { + // Add VPD ring to image. + if (!bRingAlreadyAdded) { + sizeImageOut = sizeImageOutMax; + rcLoc = 0; + if (i_sysPhase==0) { + // Add VPD ring to --->>> IPL <<<--- image + rcLoc = write_vpd_ring_to_ipl_image( + imageOut, + sizeImageOut, + (CompressedScanData*)bufVpdRing, //HB buf1 + ddLevel, + i_sysPhase, + (char*)(ring_id_list+iRing)->ringNameImg, + (void*)i_buf2, //HB buf2 + i_sizeBuf2); + } + else { + // Add VPD ring to --->>> SLW <<<--- image + rcLoc = write_vpd_ring_to_slw_image( + imageOut, + sizeImageOut, + (CompressedScanData*)bufVpdRing, //HB buf1 + ddLevel, + i_sysPhase, + (char*)(ring_id_list+iRing)->ringNameImg, + (void*)i_buf2, //HB buf2 + i_sizeBuf2, + (ring_id_list+iRing)->bWcSpace); + } + if (rcLoc) { + if (i_sysPhase==0) { + FAPI_ERR("write_vpd_ring_to_ipl_image() failed w/rc=%i",rcLoc); + } + else { + FAPI_ERR("write_vpd_ring_to_slw_image() failed w/rc=%i",rcLoc); + } + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_WRITE_VPD_RING_TO_IMAGE_ERROR); + return rc; + } + if (chipletIdVpd==0xFF) + bRingAlreadyAdded = 1; + } + } + } + } + } + } } #endif i_imageOut = imageOut; - rcLoc = sbe_xip_image_size( imageOut, &io_sizeImageOut); + sbe_xip_image_size( imageOut, &io_sizeImageOut); return FAPI_RC_SUCCESS; diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/sbe_xip_image.h b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/sbe_xip_image.h index 200277d39..3bf222ade 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/sbe_xip_image.h +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/sbe_xip_image.h @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -23,7 +23,7 @@ #ifndef __SBE_XIP_IMAGE_H #define __SBE_XIP_IMAGE_H -// $Id: sbe_xip_image.h,v 1.18 2012/07/06 20:03:09 bcbrock Exp $ +// $Id: sbe_xip_image.h,v 1.20 2013/02/06 04:48:45 bcbrock Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/sbe/sbe_xip_image.h,v $ //----------------------------------------------------------------------------- // *! (C) Copyright International Business Machines Corp. 2011 @@ -74,7 +74,7 @@ /// @{ // -*- DO NOT REORDER OR EDIT THIS SET OF CONSTANTS WITHOUT ALSO EDITING -*- -// -*- THE ASSEMBLER LAYOUT IN sbe_xip_header.S. -*- +// -*- THE ASSEMBLER LAYOUT IN sbe_xip_header.H. -*- #define SBE_XIP_SECTION_HEADER 0 #define SBE_XIP_SECTION_FIXED 1 @@ -90,8 +90,8 @@ #define SBE_XIP_SECTION_PIBMEM1 11 #define SBE_XIP_SECTION_RINGS 12 #define SBE_XIP_SECTION_SLW 13 -#define SBE_XIP_SECTION_RESERVED_1 14 -#define SBE_XIP_SECTION_RESERVED_0 15 +#define SBE_XIP_SECTION_FIT 14 +#define SBE_XIP_SECTION_FFDC 15 #define SBE_XIP_SECTIONS 16 @@ -116,8 +116,8 @@ ".pibmem1", \ ".rings", \ ".slw", \ - ".reserved_1", \ - ".reserved_0" \ + ".fit", \ + ".ffdc", \ } /// Applications can use this macro to safely index the array of section @@ -1091,6 +1091,8 @@ int sbe_xip_delete_section(void* io_image, const int i_sectionId); +#ifndef PPC_HYP + /// Duplicate a section from an SBE-XIP image in host memory /// /// \param[in,out] i_image A pointer to an SBE-XIP image in host memory. The @@ -1123,6 +1125,8 @@ sbe_xip_duplicate_section(const void* i_image, void** o_duplicate, uint32_t* o_size); +#endif // PPC_HYP + /// Append binary data to an SBE-XIP image held in host memory /// diff --git a/src/usr/hwpf/hwp/chip_attributes.xml b/src/usr/hwpf/hwp/chip_attributes.xml index 9908dee9e..92ee9c6ae 100644 --- a/src/usr/hwpf/hwp/chip_attributes.xml +++ b/src/usr/hwpf/hwp/chip_attributes.xml @@ -5,7 +5,7 @@ <!-- --> <!-- IBM CONFIDENTIAL --> <!-- --> -<!-- COPYRIGHT International Business Machines Corp. 2012 --> +<!-- COPYRIGHT International Business Machines Corp. 2012,2013 --> <!-- --> <!-- p1 --> <!-- --> @@ -151,4 +151,18 @@ <array>32</array> <platInit/> </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_EX_L2_SINGLE_MEMBER_ENABLE</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description> + Vector to communicate to SBE which EX chiplets must be configured with L2 in single member mode. + One bit per EX chiplet, bit location aligned to chiplet ID + (bit 16: EX00, bit 17: EX01, bit 18: EX02 ... bit 31: EX15) + EX chiplets whose L2 must run in single member mode are marked by a '1'. + </description> + <valueType>uint32</valueType> + <platInit/> + </attribute> + <!-- ********************************************************************* --> </attributes> diff --git a/src/usr/hwpf/hwp/common_attributes.xml b/src/usr/hwpf/hwp/common_attributes.xml index d975f730e..18988dda7 100644 --- a/src/usr/hwpf/hwp/common_attributes.xml +++ b/src/usr/hwpf/hwp/common_attributes.xml @@ -1,25 +1,25 @@ -<!-- IBM_PROLOG_BEGIN_TAG - This is an automatically generated prolog. - - $Source: src/usr/hwpf/hwp/common_attributes.xml $ - - IBM CONFIDENTIAL - - COPYRIGHT International Business Machines Corp. 2012 - - p1 - - Object Code Only (OCO) source materials - Licensed Internal Code Source Materials - IBM HostBoot Licensed Internal Code - - The source code for this program is not published or other- - wise divested of its trade secrets, irrespective of what has - been deposited with the U.S. Copyright Office. - - Origin: 30 - - IBM_PROLOG_END_TAG --> +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/common_attributes.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- COPYRIGHT International Business Machines Corp. 2012,2013 --> +<!-- --> +<!-- p1 --> +<!-- --> +<!-- Object Code Only (OCO) source materials --> +<!-- Licensed Internal Code Source Materials --> +<!-- IBM HostBoot Licensed Internal Code --> +<!-- --> +<!-- The source code for this program is not published or otherwise --> +<!-- divested of its trade secrets, irrespective of what has been --> +<!-- deposited with the U.S. Copyright Office. --> +<!-- --> +<!-- Origin: 30 --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> <!-- XML file specifying HWPF attributes. These are platInit attributes associated with multiple target types @@ -75,49 +75,4 @@ <valueType>uint32</valueType> <platInit/> </attribute> - <attribute> - <id>ATTR_EI_BUS_TX_LANE_INVERT</id> - <targetType> - TARGET_TYPE_MCS_CHIPLET,TARGET_TYPE_MEMBUF_CHIP,TARGET_TYPE_ABUS_ENDPOINT - </targetType> - <description> - Source: MRW: Downstream N/P Lane Swap Mask and Upstream N/P Lane Swap Mask - Usage: TX_LANE_INVERT initfile setting for DMI and A buses - This attribute represents the polarity of a differential wire pair - on the DMI and A buses. Normally differential pair wires are connected - between the two positive phases of the pair and the two negative phases - between two chips. In the DMI and Abus designs it's allowable for the - board designer to wire the positive phase of a lane from one chip to - the negative phase of the other chip on that same lane and vice versa - in order to simplify wiring on the board and reduce the number of - board layers. This attribute is set up as a 32 bit uint value - interpreted as a 32 bit binary vector where the left-most bit position - (msb/bit0) corresponds to the polarity of lane 0 and the right-most bit - position (lsb/bit31) corresponds to lane 31. A binary 1 in any - position in the attribute means that the board designer has done a - polarity swap within the differential pair and the initfile must set - the tx_lane_invert bit in the driving chip for that wire pair (called a lane). - The Downstream N/P Lane Swap Mask from the MRW represents the polarity - of the bus wiring as it goes from the master chip to the slave chip - (master chip is defined as the chip with a lower value of - (node*100 + chip position) and Upstream N/P Lane Swap Mask represents - the polarity of the bus wiring as it goes from the slave chip back to - the master chip. - Examples: - - Port A2 on Chip Target n0p0 connects to Port A2 on chip target - n0p2. This connection has a Downstream N/P Lane Swap Mask and - an Upstream N/P Lane Swap Mask. Setting the Downstream N/P - Lane Swap Mask to a value of 0x80000000 means lane 0 is polarity - swapped and the initfile should set lane 0's tx_lane_invert bit - on the n0p0 targeted chip (the so-called master chip). - If the Upstream N/P Lane Swap Mask is 0x20000000 this means lane - 2 is polarity swapped and the initfile should set lane 2's - tx_lane_invert bit on the n0p2 targeted chip (the so-called slave chip). - It is up to the platform code to set up each ATTR_EI_BUS_TX_LANE_INVERT - value for the correct target endpoints, ie. 0x80000000 for n0p0 and - 0x20000000 for n0p2. - </description> - <valueType>uint32</valueType> - <platInit/> - </attribute> </attributes> diff --git a/src/usr/hwpf/hwp/ei_bus_attributes.xml b/src/usr/hwpf/hwp/ei_bus_attributes.xml index 6824c67dd..1f56ec18b 100755 --- a/src/usr/hwpf/hwp/ei_bus_attributes.xml +++ b/src/usr/hwpf/hwp/ei_bus_attributes.xml @@ -5,7 +5,7 @@ <!-- --> <!-- IBM CONFIDENTIAL --> <!-- --> -<!-- COPYRIGHT International Business Machines Corp. 2012 --> +<!-- COPYRIGHT International Business Machines Corp. 2012,2013 --> <!-- --> <!-- p1 --> <!-- --> @@ -27,7 +27,7 @@ <attributes> <!-- ********************************************************************* --> - <attribute> +<!-- <attribute> <id>ATTR_EI_BUS_RX_MSB_LSB_SWAP</id> <targetType>TARGET_TYPE_MCS_CHIPLET,TARGET_TYPE_MEMBUF_CHIP,TARGET_TYPE_ABUS_ENDPOINT</targetType> <description> @@ -45,4 +45,78 @@ <valueType>uint8</valueType> <platInit/> </attribute> +--> + <attribute> + <id>ATTR_EI_BUS_TX_MSBSWAP</id> + <targetType>TARGET_TYPE_MCS_CHIPLET,TARGET_TYPE_MEMBUF_CHIP,TARGET_TYPE_ABUS_ENDPOINT</targetType> + <description> + Source: MRW: Downstream MSB Swap and Upstream MSB Swap + Usage: TX_MSBSWAP initfile setting for DMI and A buses + + This attribute represents whether or not a single clock group bus such as DMI and A bus was wired by the board designer using a feature + called MSB Swap where lane 0 of the TX chip wires to lane n-1 on the RX chip where 'n' is the width of the bus. A basic description + of this capability is that the board designer can save layers on the board wiring by crossing the wiring between the two chips in + a prescribed manner. In a non-MSB Swapped bus Lane 0 on the TX chip wires to lane 0 on the RX chip, lane 1 to lane 1 and so on. + If a bus is MSB Swapped then lane 0 of the TX chip wires to lane 'n-1' of the RX chip, lane 1 to lane 'n-2', etc. Random or + arbitrary wiring of TX to RX lanes on different chips is NOT ALLOWED. + + The Master Chip of two connected chips is defined as the chip with the smaller value of (100*Node + Pos). + The Slave Chip of two connected chips is defined as the chip with the larger value of (100*Node + Pos). + The Downstream direction is defined as the direction from the Master chip to the Slave chip. + The Upstream direction is defined as the direction from the Slave chip to the Master chip. + + The Downstream TX_MSBSWAP from the MRW is a uint8 value. 0x01 means the Downstream bus is wired msb to lsb etc. and + 0x00 means the bus is wired normally, msb to msb, lsb to lsb (lane0 to lane0). + + The Upstream TX_MSBSWAP from the MRW is a uint8 value. 0x01 means the Upstream bus is wired msb to lsb etc. and + 0x00 means the bus is wired normally, msb to msb, lsb to lsb (lane0 to lane0). + + It is up to the platform code to set up each ATTR_EI_BUS_TX_MSBSWAP value for the correct target endpoints. + + </description> + <valueType>uint8</valueType> + <platInit/> + </attribute> + <attribute> + <id>ATTR_EI_BUS_TX_LANE_INVERT</id> + <targetType>TARGET_TYPE_MCS_CHIPLET,TARGET_TYPE_MEMBUF_CHIP,TARGET_TYPE_ABUS_ENDPOINT</targetType> + <description> + Source: MRW: Downstream N/P Lane Swap Mask and Upstream N/P Lane Swap Mask + upstream-n-p-lane-swap-mask => Slave chip ATTR_EI_BUS_TX_LANE_INVERT + downstream-n-p-lane-swap-mask => Master chip ATTR_EI_BUS_TX_LANE_INVERT + Usage: TX_LANE_INVERT initfile setting for DMI and A buses + This attribute represents the polarity of a differential wire pair on the DMI and A buses. Normally differential pair + wires are connected between the two positive phases of the pair and the two negative phases between two chips. In the DMI + and Abus designs it's allowable for the board designer to wire the positive phase of a lane from one chip to the negative phase of the + of the other chip on that same lane and vice versa in order to simplify wiring on the board and reduce the number of board layers. + This attribute is set up as a 32 bit uint value interpreted as a 32 bit binary vector where the left-most bit position (msb/bit0) + corresponds to the polarity of lane 0 and the right-most bit position (lsb/bit31) corresponds to lane 31. + A binary 1 in any position in the attribute means that the board designer has done a polarity swap within the differential + pair and the initfile must set the tx_lane_invert bit in the driving chip for that wire pair (called a lane). + The Downstream N/P Lane Swap Mask from the MRW represents the polarity of the bus wiring as it goes from the master chip to + the slave chip (master chip is defined as the chip with a lower value of (node*100 + chip position) and + Upstream N/P Lane Swap Mask represents the polarity of the bus wiring as it goes from the slave chip back to the master chip. + Examples: + - Port A2 on Chip Target n0p0 connects to Port A2 on chip target n0p2. This connection has a Downstream N/P Lane Swap Mask and + an Upstream N/P Lane Swap Mask. Setting the Downstream N/P Lane Swap Mask to a value of 0x80000000 means lane 0 is polarity + swapped and the initfile should set lane 0's tx_lane_invert bit on the n0p0 targeted chip (the so-called master chip). + If the Upstream N/P Lane Swap Mask is 0x20000000 this means lane 2 is polarity swapped and the initfile should set lane 2's + tx_lane_invert bit on the n0p2 targeted chip (the so-called slave chip). + It is up to the platform code to set up each ATTR_EI_BUS_TX_LANE_INVERT value for the correct target endpoints, + ie. 0x80000000 for n0p0 and 0x20000000 for n0p2. + </description> + <valueType>uint32</valueType> + <platInit/> + </attribute> + + <attribute> + <id>ATTR_DMI_REFCLOCK_SWIZZLE</id> + <targetType>TARGET_TYPE_MCS_CHIPLET</targetType> + <description> + Defines Murano/Venice FSI GP8 refclock enable field bit offset (0:7) associated with this MCS chip unit. + </description> + <valueType>uint8</valueType> + <platInit/> + </attribute> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index 485e607cd..c77b8585b 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -10243,4 +10243,83 @@ Measured in GB</description> <readable/> </attribute> +<!-- TODO: RTC story 64824: Need to review this attribute. Per John F, it calls VPD func to provide the value --> +<attribute> + <id>EX_L2_SINGLE_MEMBER_ENABLE</id> + <description> + Vector to communicate to SBE which EX chiplets must be configured with L2 in single member mode. + One bit per EX chiplet, bit location aligned to chiplet ID + (bit 16: EX00, bit 17: EX01, bit 18: EX02 ... bit 31: EX15) + EX chiplets whose L2 must run in single member mode are marked by a '1'. + </description> + <simpleType> + <uint32_t></uint32_t> + </simpleType> + <persistency>volatile</persistency> + <readable/> + <hwpfToHbAttrMap> + <id>ATTR_EX_L2_SINGLE_MEMBER_ENABLE</id> + <macro>DIRECT</macro> + </hwpfToHbAttrMap> +</attribute> + +<!-- Note: This attribute is only used by FSP --> +<attribute> + <id>DMI_REFCLOCK_SWIZZLE</id> + <description> + Defines Murano/Venice FSI GP8 refclock enable field bit offset (0:7) associated with this MCS chip unit. + </description> + <simpleType> + <uint8_t> + <default>0</default> + </uint8_t> + </simpleType> + <persistency>non-volatile</persistency> + <readable/> + <hwpfToHbAttrMap> + <id>ATTR_DMI_REFCLOCK_SWIZZLE</id> + <macro>DIRECT</macro> + </hwpfToHbAttrMap> +</attribute> + +<!-- TODO: RTC story 64824: Need to review this attribute and handle MRW data properly --> +<attribute> + <id>EI_BUS_TX_MSBSWAP</id> + <description> + Source: MRW: Downstream MSB Swap and Upstream MSB Swap + Usage: TX_MSBSWAP initfile setting for DMI and A buses + + This attribute represents whether or not a single clock group bus such as DMI and A bus was wired by the board designer using a feature + called MSB Swap where lane 0 of the TX chip wires to lane n-1 on the RX chip where 'n' is the width of the bus. A basic description + of this capability is that the board designer can save layers on the board wiring by crossing the wiring between the two chips in + a prescribed manner. In a non-MSB Swapped bus Lane 0 on the TX chip wires to lane 0 on the RX chip, lane 1 to lane 1 and so on. + If a bus is MSB Swapped then lane 0 of the TX chip wires to lane 'n-1' of the RX chip, lane 1 to lane 'n-2', etc. Random or + arbitrary wiring of TX to RX lanes on different chips is NOT ALLOWED. + + The Master Chip of two connected chips is defined as the chip with the smaller value of (100*Node + Pos). + The Slave Chip of two connected chips is defined as the chip with the larger value of (100*Node + Pos). + The Downstream direction is defined as the direction from the Master chip to the Slave chip. + The Upstream direction is defined as the direction from the Slave chip to the Master chip. + + The Downstream TX_MSBSWAP from the MRW is a uint8 value. 0x01 means the Downstream bus is wired msb to lsb etc. and + 0x00 means the bus is wired normally, msb to msb, lsb to lsb (lane0 to lane0). + + The Upstream TX_MSBSWAP from the MRW is a uint8 value. 0x01 means the Upstream bus is wired msb to lsb etc. and + 0x00 means the bus is wired normally, msb to msb, lsb to lsb (lane0 to lane0). + + It is up to the platform code to set up each ATTR_EI_BUS_TX_MSBSWAP value for the correct target endpoints. + + </description> + <simpleType> + <uint8_t> + </uint8_t> + </simpleType> + <persistency>non-volatile</persistency> + <readable/> + <hwpfToHbAttrMap> + <id>ATTR_EI_BUS_TX_MSBSWAP</id> + <macro>DIRECT</macro> + </hwpfToHbAttrMap> +</attribute> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index 0a3c178ee..2bc56c6bf 100644 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -431,6 +431,7 @@ <attribute><id>PROC_PB_BNDY_DMIPLL_SCAN_SELECT</id></attribute> <attribute><id>PROC_AB_BNDY_PLL_SCAN_SELECT</id></attribute> <attribute><id>PROC_PCI_BNDY_PLL_SCAN_SELECT</id></attribute> + <attribute><id>EX_L2_SINGLE_MEMBER_ENABLE</id></attribute> </targetType> <targetType> @@ -625,6 +626,7 @@ <attribute><id>EI_BUS_TX_MSB_LSB_SWAP</id></attribute> <attribute><id>PEER_TARGET</id></attribute> <attribute><id>EI_BUS_TX_LANE_INVERT</id></attribute> + <attribute><id>EI_BUS_TX_MSBSWAP</id></attribute> </targetType> <targetType> @@ -890,6 +892,8 @@ <attribute><id>EI_BUS_TX_MSB_LSB_SWAP</id></attribute> <attribute><id>IBSCOM_MCS_BASE_ADDR</id></attribute> <attribute><id>EI_BUS_TX_LANE_INVERT</id></attribute> + <attribute><id>DMI_REFCLOCK_SWIZZLE</id></attribute> + <attribute><id>EI_BUS_TX_MSBSWAP</id></attribute> </targetType> <targetType> @@ -1011,6 +1015,7 @@ <attribute><id>VPD_REC_NUM</id></attribute> <attribute><id>MSS_PSRO</id></attribute> <attribute><id>MSS_NWELL_MISPLACEMENT</id></attribute> + <attribute><id>EI_BUS_TX_MSBSWAP</id></attribute> </targetType> <!-- Centaur MBS --> |

